Accessing the iPhone Camera and Photo Library (iOS 6)
Previous | Table of Contents | Next |
Using iOS 6 Event Kit to Create Date and Location Based Reminders | An Example iOS 6 iPhone Camera Application |
Learn SwiftUI and take your iOS Development to the Next Level |
The iOS 6 SDK provides access to both the iPhone camera device and photo library through the UIImagePickerController class. This allows videos and photographs to be taken from within an iPhone application and for existing photos and videos to be presented to the user for selection.
This chapter will cover the basics and some of the theory behind the use of the UIImagePickerController class before working through the step by step creation of an example application in An Example iOS 6 iPhone Camera Application.
The iOS 6 UIImagePickerController Class
The ultimate purpose of the UIImagePickerController class is to provide applications with either an image or video. It achieves this task by providing the user with access to the camera, camera roll and photo libraries on the device. In the case of the camera, the user is able to either take a photo or record a video depending on the capabilities of the device and the application’s configuration of the UIImagePickerController object. In terms of camera roll and library access, the object provides the application with the existing image or video selected by the user. The controller also allows new photos and videos created within the application to be saved to the library.
Creating and Configuring a UIImagePickerController Instance
In order to use the UIImagePickerController, an instance of the class must first be created. In addition, properties of the instance need to be configured to control the source for the images or videos (camera, camera roll or library). Further, the types of media that are acceptable to the application must also be defined (photos, videos or both). Another configuration option defines whether the user has the option to edit a photo once it has been taken and before it is passed to the application.
The source of the media is defined by setting the sourceType property of the UIImagePickerController object to one of the three supported types:
- UIImagePickerControllerSourceTypeCamera
- UIImagePickerControllerSourceTypeSavedPhotosAlbum
- UIImagePickerControllerSourceTypePhotoLibrary
The types of media acceptable to the application are defined by setting the mediaTypes property, an NSArray object that can be configured to support both video and images. The KUTTypeImage and KUTTypeMovie definitions contained in the <MobileCoreServices/MobileCoreServices.h> include file can be used as values when configuring this property.
Whether or not the user is permitted to perform editing before the image is passed on to the application is controlled via the allowsEditing boolean property. The following code creates a UImagePickerController instance and configures it for camera use with movie and image support and editing allowed. It then displays the controller and releases the controller object:
UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init]; imagePicker.delegate = self; imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera; imagePicker.mediaTypes = @[(NSString *) kUTTypeImage, (NSString *) kUTTypeMovie]; imagePicker.allowsEditing = YES; [self presentViewController:imagePicker animated:YES completion:nil];
It should be noted that the above code also configured the current class as the delegate for the UIImagePickerController instance. This is actually a key part of how the class works and is covered in the next section.
Configuring the UIImagePickerController Delegate
When the user is presented with the UIImagePickerController object user interface the application essentially hands control to that object. That being the case, the controller needs some way to notify the application that the user has taken a photo, recorded a video or made a library selection. It does this by calling delegate methods. The class that instantiates a UIImagePickerController instance should, therefore, declare itself as the object’s delegate, conform to the UIImagePickerControllerDelegate and UINavigationControllerDelegate protocols and implement the didFinishPickingMediaWithInfo and imagePickerControllerDidCancel methods. When the user has selected or created media, the didFinishPickingMediaWithInfo method is called and passed an NSDictionary object containing the media and associated data. In the event that the user cancels the operation the imagePickerControllerDidCancel method is called. In both cases it is the responsibility of the delegate method to dismiss the view controller:
-(void)imagePickerController: (UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info { // Code here to work with media [self dismissViewControllerAnimated:YES completion:nil]; } -(void)imagePickerControllerDidCancel: (UIImagePickerController *)picker { [self dismissViewControllerAnimated:YES completion:nil]; }
The info argument passed to the didFinishPickingMediaWithInfo method is an NSDictionary object containing the data relating to the image or video created or selected by the user. The first step is typically to identify the type of media:
NSString *mediaType = info[UIImagePickerControllerMediaType]; if ([mediaType isEqualToString:(NSString *)kUTTypeImage]) { // Media is an image } else if ([mediaType isEqualToString:(NSString *)kUTTypeMovie]) { // Media is a video }
The original, unedited image selected or photographed by the user may be obtained from the info dictionary as follows:
UIImage *image = info[UIImagePickerControllerOriginalImage];
Assuming that editing was enabled on the image picker controller object, the edited version of image may be accessed via the UImagePickerControllerEditedImage dictionary key:
UIImage *image = info[UIImagePickerControllerEditedImage];
If the media is a video, the URL of the recorded media may be accessed as follows:
NSURL *url = info[UIImagePickerControllerMediaURL];
Once the image or video URL has been obtained the application can optionally save the media to the library and either display the image to the user or play the video using the MPMoviePlayer class as outlined in the chapter entitled Video Playback from within an iOS 6 iPhone Application.
Detecting Device Capabilities
Not all iOS devices provide the same functionality. iPhone models prior to the 3GS model, for example, do not support the recording of video. Some iPod Touch models do not have a camera so neither the camera, nor camera roll are available via the image picker controller. These differences in functionality make it important to detect the capabilities of a device when using the UIImagePickerController class. Fortunately, this may easily be achieved by a call to the isSourceTypeAvailable class method of the UIImagePickerController. For example, to detect the presence of a camera:
if ([UIImagePickerController isSourceTypeAvailable: UIImagePickerControllerSourceTypeCamera]) { // code here }
Similarly, to test for access to the camera roll:
if ([UIImagePickerController isSourceTypeAvailable: UIImagePickerControllerSourceTypeSavedPhotosAlbum]) { // code here }
Finally, to check for support for photo libraries:
if ([UIImagePickerController isSourceTypeAvailable: UIImagePickerControllerSourceTypePhotoLibrary]) { // code here }
Saving Movies and Images
Once a video or photo created by the user using the camera is handed off to the application it is then the responsibility of the application code to save that media into the library. Photos and videos may be saved via calls to the UIImageWriteToSavedPhotosAlbum and UISaveVideoAtPathToSavedPhotosAlbum methods respectively. These methods use a target-action mechanism whereby the save action is initiated and the application continues to run. When the action is complete a specified method is called to notify the application of the success or otherwise of the operation.
To save an image:
UIImageWriteToSavedPhotosAlbum(image, self, @selector(image:finishedSavingWithError:contextInfo:), nil);
To save a video:
if (UIVideoAtPathIsCompatibleWithSavedPhotosAlbum(videoPath)) { UISaveVideoAtPathToSavedPhotosAlbum(videoPath, self, @selector(video:finishedSavingWithError:contextInfo:), nil); }
Last, but by no means least, is the finishedSavingWithError method which will be called when the action is either complete or failed due to an error:
-(void)image:(UIImage *)image finishedSavingWithError:(NSError *) error contextInfo:(void *)contextInfo { if (error) { UIAlertView *alert = [[UIAlertView alloc] initWithTitle: @"Save failed" message: @"Failed to save image/video" delegate: nil cancelButtonTitle:@"OK" otherButtonTitles:nil]; [alert show]; } }
Summary
In this chapter we have provided an overview of the UIImagePickerController and looked at how this class can be used either to allow a user to take a picture or record video from within an iPhone application or select media from the device photo libraries. Now that the theory has been covered, the next chapter entitled An Example iOS 6 iPhone Camera Application will work through the development of an example application designed to implement the theory covered in this chapter.
Learn SwiftUI and take your iOS Development to the Next Level |
Previous | Table of Contents | Next |
Using iOS 6 Event Kit to Create Date and Location Based Reminders | An Example iOS 6 iPhone Camera Application |