Tuesday 17 June 2014

Asynchronous Operations in iOS with Grand Central Dispatch

Grand Central Dispatch, or GCD for short, is a C API that makes it exceptionally easy to perform asynchronous operations in iOS. Asynchronous operations are a fundamental part of every iOS app when you want to perform long operations without freezing or blocking the user interface. You can image that if your entire app froze without warning then your users would get quite irritated.
With GCD, you can line up blocks of code in a queue for the system to execute as necessary. These blocks or operations, will be dispatched in the queue to another thread, leaving your main UI thread to continue its tasks. It’s important to know that GCD will use separate threads for it’s operations but which thread it isn’t important to you. All that matters is that your long running process in a separate thread outside the main thread where your UI and gestures are running.

GCD queues can be concurrent or serial but serial queues (where there is one queue and each item is executed one after the other in order) are easier to understand so we’ll look at those.
The more important functions you’ll need are for creating the queue:

dispatch_queue_t dispatch_queue_create(const char *label, dispatch_queue_attr_t attr);
and adding blocks to the queue:

void dispatch_async(dispatch_queue_t queue, dispatch_block_t block);
 
There’s also a couple helper functions for retrieving specific queues such as:
dispatch_queue_t dispatch_get_current_queue(void);
dispatch_queue_t dispatch_get_main_queue(void);
 
The dispatch_get_current_queue function will return the current queue from which the block is dispatched and the dispatch_get_main_queue function will return the main queue where your UI is running.

The dispatch_get_main_queue function is very useful for updating the iOS app’s UI as UIKit methods are not thread safe (with a few exceptions) so any calls you make to update UI elements must always be done from the main queue.

A typical GCD call would look something like this:
// Doing something on the main thread

dispatch_queue_t myQueue = dispatch_queue_create("My Queue",NULL);
dispatch_async(myQueue, ^{
    // Perform long running process
    
    dispatch_async(dispatch_get_main_queue(), ^{
        // Update the UI
        
    });
}); 

// Continue doing other stuff on the 
// main thread while process is running.
GCD relies on block so it has a really nice, readable syntax. It becomes clear what happes in the background thread and the main thread. For example, here’s how you might load a few images:
NSArray *images = @[@"http://example.com/image1.png",
                 @"http://example.com/image2.png",
                 @"http://example.com/image3.png",
                 @"http://example.com/image4.png"];

dispatch_queue_t imageQueue = dispatch_queue_create("Image Queue",NULL);

for (NSString *urlString in images) {
    dispatch_async(imageQueue, ^{
        
        NSURL *url = [NSURL URLWithString:urlString];
        NSData *imageData = [NSData dataWithContentsOfURL:url];
        UIImage *image = [UIImage imageWithData:imageData];

        NSUInteger imageIndex = [images indexOfObject:urlString];
        UIImageView *imageVIew = (UIImageView *)[self.view viewWithTag:imageIndex];
        
        if (!imageView) return;
        
        dispatch_async(dispatch_get_main_queue(), ^{
            // Update the UI
            [imageVIew setImage:image];
        });
        
    }); 
}

// Continue doing other stuff while images load.
 
You’ll notice I check for imageView before dispatching to the main thread. This avoids the main queue dispatch if the network request took a long time and the imageView is no longer there for one reason or another. Once a block has been dispatched onto a queue, it’s not possible to stop it. The block will execute to completion and there’s nothing you can do. If you have a very long running process, such as loading a URL, you should add logic between each step to check to see if it should continue and if it’s still appropriate to finish the operation.
That’s it. Start build queues and making your UI more responsive.

Aside: Concurrency

If you want to run a single independent queued operation and you’re not concerned with other concurrent operations, you can use the global concurrent queue:
dispatch_queue_t globalConcurrentQueue =
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
This will return a concurrent queue with the given priority as outlined in the documentation:
DISPATCH_QUEUE_PRIORITY_HIGH Items dispatched to the queue will run at high priority, i.e. the queue will be scheduled for execution before any default priority or low priority queue.
DISPATCH_QUEUE_PRIORITY_DEFAULT Items dispatched to the queue will run at the default priority, i.e. the queue will be scheduled for execution after all high priority queues have been scheduled, but before any low priority queues have been scheduled.
DISPATCH_QUEUE_PRIORITY_LOW Items dispatched to the queue will run at low priority, i.e. the queue will be scheduled for execution after all default priority and high priority queues have been scheduled.
DISPATCH_QUEUE_PRIORITY_BACKGROUND Items dispatched to the queue will run at background priority, i.e. the queue will be scheduled for execution after all higher priority queues have been scheduled and the system will run items on this queue on a thread with background status as per setpriority(2) (i.e. disk I/O is throttled and the thread’s scheduling priority is set to lowest value).
from queue.h

 

Friday 13 June 2014

How to find iPhone UDID in iphone 5, 5C & 5S iOS7 : 

What is the UDID?

Each iPhone or iPod Touch has a Unique Device Identifier (UDID), which is a sequence of 40 letters and numbers that is specific to your device. It’s like a serial number but much harder to guess. Apple has hidden the UDID from all public APIs, starting with iOS 7. Any UDID that begins with FFFF is a fake ID. The "Send UDID" apps that previously worked can no longer be used to gather UDID for test devices.

How do I get my UDID?

Easy Way .. Copy/Paste from iTunes
  1. Launch iTunes and connect your iPhone.
  2. In the right pane, locate the information about your iPhone, including its name, capacity, software version, serial number, and phone number.
  3. Reveal the Identifier by clicking on Serial Number:. Copy the Identifier to your clipboard by choosing Edit → Copy.

More Easy ? UDID app !!

There are a number of free apps that will tell you the UDID for your iOS device.
  1. http://whatsmyudid.com
  2. http://get.udid.io Wait..

Are you an iOS developer ? Well try this..

UDID is no longer available in iOS 6+ due to security / privacy reasons. Instead, use identifierForVendor or advertisingIdentifier.


identifierForVendor: An alphanumeric string that uniquely identifies a device to the app’s vendor. (read-only) The value of this property is the same for apps that come from the same vendor running on the same device. A different value is returned for apps on the same device that come from different vendors, and for apps on different devices regardless of vendor.

You can use identifierForVendor after that store them to keychain and use later. Because value of keychain will not changed when re-install app.


advertisingIdentifier: An alphanumeric string unique to each device, used only for serving advertisements. (read-only) Unlike the identifierForVendor property of UIDevice, the same value is returned to all vendors. This identifier may change—for example, if the user erases the device—so you should not cache it.

Check out OpenUDID: Open source initiative for a universal and persistent UDID solution for iOS http://OpenUDID.org

OpenUDID is a drop-in replacement for the deprecated uniqueIdentifier property of the UIDevice class on iOS (a.k.a. UDID) and otherwise is an industry-friendly equivalent for iOS and Android, and most recently Windows C# and Silverlight (see links above).
Also We can use identifierForVendor for ios7,

-(NSString*)uniqueIDForDevice
{
    NSString* uniqueIdentifier = nil;
// >=iOS 7 
if( [UIDevice instancesRespondToSelector:@selector(identifierForVendor)] ){
        uniqueIdentifier = [[[UIDevice currentDevice] identifierForVendor] UUIDString];
    } else { //<=iOS6, Use UDID of Device       
            CFUUIDRef uuid = CFUUIDCreate(NULL);
            //- for non- ARC
            //uniqueIdentifier = ( NSString*)CFUUIDCreateString(NULL, uuid);
            // for ARC
            uniqueIdentifier = ( NSString*)CFBridgingRelease(CFUUIDCreateString(NULL, 
                                uuid));
            CFRelease(uuid);
         }
    }
return uniqueIdentifier;
}

 

Wednesday 11 June 2014

What is .cer, .pem, .key file?


SSL has been around for long enough you'd think that there would be agreed upon container formats. And you're right, there are. Too many standards as it happens. So this is what I know, and I'm sure others will chime in.
  • .csr This is a Certificate Signing Request. Some applications can generate these for submission to certificate-authorities. It includes some/all of the key details of the requested certificate such as subject, organization, state, whatnot, as well as the public key of the certificate to get signed. These get signed by the CA and a certificate is returned. The returned certificate is the public certificate, which itself can be in a couple of formats.
  • .pem Defined in RFC's 1421 through 1424, this is a container format that may include just the public certificate (such as with Apache installs, and CA certificate files /etc/ssl/certs), or may include an entire certificate chain including public key, private key, and root certificates. The name is from Privacy Enhanced Email, a failed method for secure email but the container format it used lives on.
  • .key This is a PEM formatted file containing just the private-key of a specific certificate. In Apache installs, this frequently resides in /etc/ssl/private. The rights on this directory and the certificates is very important, and some programs will refuse to load these certificates if they are set wrong.
  • .pkcs12 .pfx .p12 Originally defined by RSA in the Public-Key Cryptography Standards, the "12" variant was enhanced by Microsoft. This is a passworded container format that contains both public and private certificate pairs. Unlike .pem files, this container is fully encrypted. Every time I get one I have to google to remember the openssl-fu required to break it into .key and .pem files.
A few other formats that show up from time to time:
  • .der A way to encode ASN.1 syntax, a .pem file is just a Base64 encoded .der file. OpenSSL can convert these to .pem. Windows sees these as Certificate files. I've only ever run into them in the wild with Novell's eDirectory certificate authority.
  • .cert .cer A .pem formatted file with a different extension, one that is recognized by Windows Explorer as a certificate, which .pem is not.
  • .crl A certificate revocation list. Certificate Authorities produce these as a way to de-authorize certificates before expiration.

In summary, there are three different ways to present certificates and their components:
  • PEM Governed by RFCs, it's used preferentially by open-source software. It can have a variety of extensions (.pem, .key, .cer, .cert, more)
  • PKCS12 A private standard that provides enhanced security versus the plain-text PEM format. It's used preferentially by Windows systems, and can be freely converted to PEM format through use of openssl.
  • DER The parent format of PEM. It's useful to think of it as a binary version of the base64-encoded PEM file. Not routinely used by anything in common usage.
I hope this helps.

Monday 9 June 2014

Combine one UIImage onto of another UIImage : 

Check the Full Sample From Here : Sample Code

Combining two images, especially useful, if the overlay image has an alpha value:

 
#import <Foundation/Foundation.h> 
 
@interface UIImage (combine)
- (UIImage*)overlayWith:(UIImage*)overlayImage;
@end
 
 
And the implementation file.

#import "UIImage+Category.h" 
 
@implementation UIImage (combine)
 
- (UIImage*)overlayWith:(UIImage*)overlayImage {
   UIGraphicsBeginImageContext(self.size);
   [self drawAtPoint:CGPointZero];
   [overlayImage drawAtPoint:CGPointZero];
   UIImage *combinedImage = UIGraphicsGetImageFromCurrentImageContext();
   UIGraphicsEndImageContext();
   return combinedImage;
}
 
@end
 

Above i have declare the UIImage+Category Lib files for the UIImage.

You can see the below sample Example for calling the method for combining
the one image to another and set both images to one images.

You can combine multiple images using this methods.:
#import "ViewController.h"
#import "UIImage+Overlay.h"

- (void)viewDidLoad
{
    [super viewDidLoad];
    self.theImageView.image = [self mergingImage];
}

-(UIImage *)mergingImage {
    UIImage *background = [UIImage imageNamed:@"background.png"];
    UIImage *audiImage = [UIImage imageNamed:@"audi.png"];
    UIImage *combineImage = [background overlayWith:audiImage];
    return combineImage;
}
 
You can Download Transparent images from Here : images.zip 
Output of the Project : 







audi.png
 
 
 
Background.png

 
 


       +
 
 
 
 
 
Combine image
 

Friday 6 June 2014

Delete All Files in Documents Directory


The first approach I took was to loop through all the files, building a path to each, one by one:

  1. // Path to the Documents directory
  2. NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
  3. if ([paths count] > 0)
  4. {
  5.   NSError *error = nil;  
  6.   NSFileManager *fileManager = [NSFileManager defaultManager];
  7.  
  8.   // Print out the path to verify we are in the right place
  9.   NSString *directory = [paths objectAtIndex:0];
  10.   NSLog(@"Directory: %@", directory);
  11.  
  12.   // For each file in the directory, create full path and delete the file
  13.   for (NSString *file in [fileManager contentsOfDirectoryAtPath:directory error:&error])
  14.   {    
  15.     NSString *filePath = [directory stringByAppendingPathComponent:file];
  16.     NSLog(@"File : %@", filePath);
  17.  
  18.     BOOL fileDeleted = [fileManager removeItemAtPath:filePath error:&error];
  19.  
  20.     if (fileDeleted != YES || error != nil)
  21.     {
  22.       // Deal with the error...
  23.     }
  24.   }
  25.  
  26. }

 The code above works fine, however, I was interested in something that didn’t build each path separately – the code below deletes all the files in one fell swoop:

  1. NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
  2. if ([paths count] > 0)
  3. {
  4.   NSLog(@"Path: %@", [paths objectAtIndex:0]);
  5.  
  6.   NSError *error = nil;  
  7.   NSFileManager *fileManager = [NSFileManager defaultManager];
  8.  
  9.   // Remove Documents directory and all the files
  10.   BOOL deleted = [fileManager removeItemAtPath:[paths objectAtIndex:0] error:&error];
  11.  
  12.   if (deleted != YES || error != nil)
  13.   {
  14.     // Deal with the error...
  15.   }
  16.  
Given the requested item to remove was a directory, as you’d expect, not only were the files deleted, so was the Documents directory. Problem is, I ran into errors when I attempted to drag/drop new files into the file sharing areas iTunes.
To get things working again, I changed up the code above to create the Documents directory:

  1. NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
  2. if ([paths count] > 0)
  3. {
  4.   NSLog(@"Path: %@", [paths objectAtIndex:0]);
  5.  
  6.   NSError *error = nil;  
  7.   NSFileManager *fileManager = [NSFileManager defaultManager];
  8.  
  9.   // Remove all files in the documents directory
  10.   BOOL deleted = [fileManager removeItemAtPath:[paths objectAtIndex:0] error:&error];
  11.  
  12.   if (deleted != YES || error != nil)
  13.   {
  14.     // Deal with the error...
  15.   }
  16.   else
  17.     // Recreate the Documents directory
  18.     [fileManager createDirectoryAtPath:[paths objectAtIndex:0] withIntermediateDirectories:NO attributes:nil error:&error];
  19.  
  20. }
 Although there is less code to delete the Documents directory, something tells me it may simply be a better (and more robust) solution to loop and delete each file in sequence.

Wednesday 4 June 2014

Save and Load UIImage in Documents directory on iPhone:

The following function saves UIImage in test.png file in the user Document folder:


- (void)saveImage: (UIImage*)image
{
    if (image != nil)
    {
        NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, 
                      NSUserDomainMask, YES);
        NSString *documentsDirectory = [paths objectAtIndex:0];
        NSString* path = [documentsDirectory stringByAppendingPathComponent: 
                       [NSString stringWithString: @"test.png"] ];
        NSData* data = UIImagePNGRepresentation(image);
        [data writeToFile:path atomically:YES];
    }
} 
 

The following function loads UIImage from the test.png file:

- (UIImage*)loadImage { NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *documentsDirectory = [paths objectAtIndex:0]; NSString* path = [documentsDirectory stringByAppendingPathComponent: [NSString stringWithString: @"test.png"] ]; UIImage* image = [UIImage imageWithContentsOfFile:path]; return image; }

Change UITextField’s placeholder color without subclassing it

Reference URL :
1. http://stackoverflow.com/questions/1340224/iphone-uitextfield-change-placeholder-text-color

The safe way to customize UITextField’s placeholder is subclassing the UITextField and overriding placeholderRectForBounds:, Apple won’t bother you on this one. However, if you want to take the risk, you can try this way:
[self.MyTextField setValue:[UIColor darkGrayColor] forKeyPath:@"_placeholderLabel.textColor"];


if ([textField respondsToSelector:@selector(setAttributedPlaceholder:)]) {
  UIColor *color = [UIColor blackColor];
  textField.attributedPlaceholder = [[NSAttributedString alloc] 
         initWithString:placeholderText 
         attributes:@{NSForegroundColorAttributeName: color}];
} else {
  NSLog(@"Cannot set placeholder text's color, because 
            deployment target is earlier than iOS 6.0");
  // TODO: Add fall-back code to set placeholder color.
}