iOS: Save an Image in Camera Roll

Saving an image to the camera roll on the iPhone is as close as a method call in the UIKit. However, it takes a few steps to wrap together code to manage error handling and notification that the image has been saved. Let’s see how this works.

Let’s begin with the method description to save an image:

  void UIImageWriteToSavedPhotosAlbum(UIImage *image, 
                  id completionTarget, SEL completionSelector, void *contextInfo);

completionTarget refers to the object in which the completionSelector can be found. In other words, what object has the method that will be called once the file write is complete?contextInfo is a void * that you can use to specify content to be passed to thecompletionSelector.

Obviously, the image is a required paramater. The other three are only needed if you prefer to be notified asynchronously when the write is complete. Here’s how a call to the above method might look:

  // Image to save
  UIImage *img = [UIImage imageNamed:@"ImageName.png"];  

  // Request to save the image to camera roll
  UIImageWriteToSavedPhotosAlbum(img, self, 
              @selector(image:didFinishSavingWithError:contextInfo:), nil);

Here we are specifying that the selector to be called upon completion is within this object (self). A template for this selector could look as follows:

  - (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error 
             contextInfo:(void *)contextInfo
  {
    // Was there an error?
    if (error != NULL)
    {
      // Show error message...

    }
    else  // No errors
    {
      // Show message image successfully saved
    }
  }

Add code for displaying the appropriate message based on success or failure of the image save, and you’re good to go.

Advertisements

Development and Distribution Certificate iOS

How to create a development certificate:

  1. Generate a Certificate Signing Request (CSR) with a public key
    • In your Applications folder, open the Utilities folder and launch Keychain Access.
    • Choose Keychain Access > Certificate Assistant > Request a Certificate from a Certificate Authority.
    • In the Certificate Information window, enter or select the following information:
    • In the User Email Address field, enter your email address
    • In the Common Name field, enter your name
    • In the Request is group, select the Saved to disk option
    • Click Continue.
    • The Certificate Assistant saves a Certificate Signing Request (CSR) file to your Desktop.
    • The public/private key pair will be generated when you create the Certificate Signing Request (CSR) if you use the Key Chain Assistant to create the CSR.
  2. Submit the CSR through the Provisioning Portal.
    • Click the Development tab
    • Upload the certificate by choosing the file
    • Click Submit

iOS5 HTTP Post with Json Object

NSArray *keys = [NSArray arrayWithObjects:@"longitude", @"latitude", nil];
NSArray *objects = [NSArray arrayWithObjects:longitude, latitude, nil];

NSDictionary *jsonDictionary = [NSDictionary dictionaryWithObjects:objects forKeys:keys];

if([NSJSONSerialization isValidJSONObject:jsonDictionary])
{
    __jsonData = [NSJSONSerialization dataWithJSONObject:jsonDictionary options:0 error:nil];
    __jsonString = [[NSString alloc]initWithData:__jsonData encoding:NSUTF8StringEncoding];
}

// Be sure to properly escape your url string.
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:@"https://site.com...etc"];
[request setHTTPMethod:@"POST"];
[request setHTTPBody: __jsonData];
[request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
[request setValue:[NSString stringWithFormat:@"%d", [__jsonData length]] forHTTPHeaderField:@"Content-Length"];  

NSError *errorReturned = nil;
NSURLResponse *theResponse =[[NSURLResponse alloc]init];
NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&theResponse error:&errorReturned];

if (errorReturned) {
    // Handle error.
}
else
{
    NSError *jsonParsingError = nil;
    NSArray *jsonArray = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers|NSJSONReadingAllowFragments error:&jsonParsingError];
}

Passing Managed Object Context in iOS 5.x

Passing a Managed Object context to View Controllers is a challenge.  There are more than one way to do it.

  • Referencing in App Delegate
  • SubClass the ViewController
  • Prepare for Segue ( Yes this is interesting and more relevant when you are trying to build you app using latest Storyboard feature

In my current example I m loading the app with a login page which on success redirects to a TabController.

// Pass the managed object context to the root view controller (the login view)
  LoginViewController *rootView = (LoginViewController *)self.window.rootViewController;
rootView.managedObjectContext = self.managedObjectContext;


 This will make available the managed object context to first Navigation View Controller.

In LoginViewController.h we need to pass in prepareForSegue. Here the catch is topViewController as the table view controller is embedded in navigation controller.

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {     
NSString *segueIdentifier = [segue identifier];     
if ([segueIdentifier isEqualToString:@"YourSegueIdentifier"]) 
// This can be defined via Interface Builder     
{
if([segue.identifier isEqualToString:@"LoginSegue"]){  
// The controll is passed to TabBarViewController
UITabBarController *tabBarViewController = (UITabBarController *) [segue destinationViewController];
ReceiptsListViewController *receiptsListViewController = (ReceiptsListViewController *) [[[tabBarViewController viewControllers] objectAtIndex:5] topViewController];
    receiptsListViewController.managedObjectContext = self.managedObjectContext;

}