In iOS, most of the applications need the feature of capturing the picture either from camera or from the existing photo library. Further, apps require to upload or save it in application bundle for future use. In this tutorial I will explain one of the most useful feature of iOS called UIImagePickerController and its delegate protocol. I also explain how to save images into iPhone simulator’s photo library, editing the image while selecting and converting image into NSData for uploading into server or saving in application bundle.

Open Xcode, select “Create a new Xcode project,” and click Next. Choose the Single View Application. Click Next, then you navigate to the next screen. Fill all the fields like product name (ImagePicker), organization name and etc. In the bottom of the screen just uncheck “Use Storyboards”(As I have use the nib files in this application) and “Include Unit Tests”.

Before going further we need to add some images into iPhone simulator’s photo app. Open the iPhone simulator then open safari browser. Select any image from google images then tap the image and hold it for a while, you will see the action sheet appear as shown in the following figure.

Tap on “Save Image” option then image will be automatically saved into photos app.

Now open ViewController.xib file from our project and add a button and connect it with the IBAction in the ViewController.h file. Open the ViewController.m file and add the following code.

- (IBAction)addImage:(id)sender
{
    UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle: nil
                                                             delegate: self
                                                    cancelButtonTitle: @"Cancel"
                                               destructiveButtonTitle: nil
                                                    otherButtonTitles: @"Take a new photo", @"Choose from existing", nil];
    [actionSheet showInView:self.view];
}

This method will be invoked whenever you tap on “Add Image” button. In this I use UIActionSheet to populate available options. From apple documentation UIActionSheet class present the user with a set of alternatives for how to proceed with a given task. Now compile and run the code(there may be a warning but continue executing) you will see the screen as follows.

Popup is showing three options. Now we have to write action methods for first two options. For that we have to register our ViewController with UIActionSheetDelegate protocol. Add the UIActionSheetDelegate method and implement the action methods as follow.

- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
{
    switch (buttonIndex) {
        case 0:
            [self takeNewPhotoFromCamera];
            break;
        case 1:
            [self choosePhotoFromExistingImages];
        default:
            break;
    }
}

- (void)takeNewPhotoFromCamera
{
    if ([UIImagePickerController isSourceTypeAvailable: UIImagePickerControllerSourceTypeCamera])
    {
        UIImagePickerController *controller = [[UIImagePickerController alloc] init];
        controller.sourceType = UIImagePickerControllerSourceTypeCamera;
        controller.allowsEditing = NO;
        controller.mediaTypes = [UIImagePickerController availableMediaTypesForSourceType: UIImagePickerControllerSourceTypeCamera];
        controller.delegate = self;
        [self.navigationController presentViewController: controller animated: YES completion: nil];
    }
}

-(void)choosePhotoFromExistingImages
{
    if ([UIImagePickerController isSourceTypeAvailable: UIImagePickerControllerSourceTypePhotoLibrary])
    {
        UIImagePickerController *controller = [[UIImagePickerController alloc] init];
        controller.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
        controller.allowsEditing = NO;
        controller.mediaTypes = [UIImagePickerController availableMediaTypesForSourceType: UIImagePickerControllerSourceTypePhotoLibrary];
        controller.delegate = self;
        [self.navigationController presentViewController: controller animated: YES completion: nil];
    }
}

In the last two methods, first we check whether source type is available or not. If available then we present UIImagePickerController. By default allowsEditing property returns NO. If we set it to YES then we navigate to the next controller where we get the option to scale the selected image.
Now open AppDelegate.h and add the following line of code

@property (strong, nonatomic) UINavigationController *navController;

In AppDelegate.m, change our ViewController to RootViewController by adding/modifying the following lines of code in “didFinishLaunchingWithOptions” method.

self.viewController = [[ViewController alloc] initWithNibName:@"ViewController" bundle:nil];
self.navController = [[UINavigationController alloc]initWithRootViewController:self.viewController];
self.window.rootViewController = self.navController;

Now register our ViewController with UINavigationControllerDelegate, UIImagePickerControllerDelegate protocols. Because to present UIImagePickerController we need the UINavigationController delegate protocol. Implement the UIImagePickerControllerDelegate methods in ViewController.m file as follows.

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
    [self.navigationController dismissViewControllerAnimated: YES completion: nil];
    UIImage *image = [info valueForKey: UIImagePickerControllerOriginalImage];
    NSData *imageData = UIImageJPEGRepresentation(image, 0.1);
}

- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker;
{
    [self.navigationController dismissViewControllerAnimated: YES completion: nil];
}

Whenever we select the image, “didFinishPickingMediaWithInfo” delegate will be fired. There we can find the selected image reference using UIImagePickerControllerOriginalImage constant. If you want to upload the image to remote server or save it to the application bundle then we need to convert the image into NSData. we have already discuss the save image locally feature in one of our earlier tutorials (http://www.edumobile.org/iphone/miscellaneous/image-download-application-in-iphone/).

Suppose if you want to populate the selected image in a new controller then add the controller named ImageViewController as shown in the following figure.

Open ImageViewController.h file, add UIImageView property and initialize its bounds in associated .m file. Then add the following lines of code in “didFinishPickingMediaWithInfo” delegate of ViewController.m file.

ImageViewController *imageController = [[ImageViewController alloc]initWithNibName:@"ImageViewController" bundle:nil];
imageController.selectedImageView.image = image;
[self.navigationController pushViewController:imageController animated:YES];

Now compile and run the code. After selecting your options you will navigate to the photos app. If you select any image then you will navigate to the new screen where you see the selected image. If you press the “take a new photo” button in simulator, it won’t work. Because simulator is not capable of taking photos.