Thursday, 23 January 2014

Unique Identifier UUID - iOS

UDID is a hash value composed from various hardware identifiers such as the device serial number.
It is unique for each device. 
The UDID is independent of the device name, SIM card.
It is really easy to get it from the device programmatically:

NSString *uuid =  [[UIDevice currentDevice] uniqueIdentifier];

But UDID is no longer available onwards iOS 6 due to security / privacy reasons.
UDID is deprecated by Apple; developers can not make use of it in any iOS application.

So what now? How can we identify the device?

I found many solutions on searching over internet like identifierForVendor or advertisingIdentifier or generate our own UUID (store & persist it on your own).

Many examples show how to generate UUID and store it in NSUserDefault:

-(NSString *)generateUUID {
    NSString *CFUUID = nil;
    if ([[NSUserDefaults standardUserDefaults] valueForKey:@"UUID"] == nil) {
        CFUUIDRef uuid = CFUUIDCreate(kCFAllocatorDefault);
        CFUUID = (NSString *)CFBridgingRelease(CFUUIDCreateString(kCFAllocatorDefault, uuid));
        [[NSUserDefaults standardUserDefaults] setValue:CFUUID forKey:@"UUID"];
        [[NSUserDefaults standardUserDefaults] synchronize];
    } else {
        CFUUID = [[NSUserDefaults standardUserDefaults] valueForKey:@"UUID"];

But if you store the UUID in NSUserDefaults you would loose it as soon as the app gets uninstalled from the device.
So the better idea is to store it in Keychain. In case the app is uninstalled Keychain will preserve the UUID and on next installation we can fetch it from there.

Create & Store UUID in Keychain: Source Code

Friday, 10 January 2014

Upload Multiple Images/Photos to Server Using MulipartFormatData via AFNetworking

Below is the code snippet which would help in uploading multiple Images along with Text to Server:

-(void)uploadMultipleImagesWithTextMessageUsingAFNetworkingMultipartFormat:(id)sender {
    // Upload multiple images to server using multipartformatdata (AFNetworking)
    NSString *stringMessage = @"I am uploading multiple images to server";  
    AFHTTPClient *client = [[AFHTTPClient alloc] initWithBaseURL: [NSURL URLWithString:BASEURL]]; // replace BASEURL
    client.parameterEncoding = AFJSONParameterEncoding;

    NSMutableURLRequest *request = [client multipartFormRequestWithMethod:@"POST" path:@"/PostMultImagesWithTextAPI" parameters:nil constructingBodyWithBlock: ^(id <AFMultipartFormData>formData) {
        [formData appendPartWithFormData:[[[NSUserDefaults standardUserDefaults] objectForKey:KServerAccessToken] dataUsingEncoding:NSUTF8StringEncoding] name:@"AccessToken"];
        [formData appendPartWithFormData:[stringMessage dataUsingEncoding:NSUTF8StringEncoding] name:@"PostText"];
        // arrayChosenImages is NSArray of UIImage to be uploaded
        for (int i=0; i<[arrayChosenImages count]; i++) {
            [formData appendPartWithFileData:UIImageJPEGRepresentation([arrayChosenImages objectAtIndex:i], 0.5)
                                        name:[NSString stringWithFormat:@"image%d",i]
                                    fileName:[NSString stringWithFormat:@"image%d.jpg",i]
    AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
    [operation setUploadProgressBlock:^(NSUInteger bytesWritten, long long totalBytesWritten, long long totalBytesExpectedToWrite) {
        float uploadPercentge = (float)totalBytesWritten / (float)totalBytesExpectedToWrite;
        float uploadActualPercentage = uploadPercentge * 100;
        NSLog(@"Sent %lld of %lld bytes", totalBytesWritten, totalBytesExpectedToWrite);
        NSLog(@"Multipartdata upload in progress: %@",[NSString stringWithFormat:@"%.2f %%",uploadActualPercentage]);
        if (uploadActualPercentage >= 100) {
            NSLog(@"Waitting for response ...");
        progressBar.progress = uploadPercentge; //  progressBar is UIProgressView to show upload progress
    [client enqueueHTTPRequestOperation:operation];
    [operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
        NSData *dataResponseJSON = [operation.responseString dataUsingEncoding:NSUTF8StringEncoding];
        NSDictionary *dictResponseJSON = [NSJSONSerialization JSONObjectWithData:dataResponseJSON options:NSJSONReadingMutableContainers error:nil];
        NSLog(@"PostMultImagesWithTextAPI API Response: %@", dictResponseJSON);      
     failure:^(AFHTTPRequestOperation *operation, NSError *error) {
         NSLog(@"PostMultImagesWithTextAPI API failed with error: %@", operation.responseString);
    [operation start];

Hope it helps you...