Accessing the iOS 10 Camera and Photo Library
Previous | Table of Contents | Next |
Using iOS 10 Event Kit to Create Date and Location Based Reminders | An Example iOS 10 iPhone Camera Application |
Learn SwiftUI and take your iOS Development to the Next Level |
The iOS 10 SDK provides access to both the camera device and photo library through the UIImagePickerController class. This allows videos and photographs to be taken from within an 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 10 Camera Application.
The 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:
• UIImagePickerControllerSourceType.camera
• UIImagePickerControllerSourceType.savedPhotosAlbum
• UIImagePickerControllerSourceType.photoLibrary
The types of media acceptable to the application are defined by setting the mediaTypes property, an Array object that can be configured to support both video and images. The kUTTypeImage and kUTTypeMovie definitions contained in the MobileCoreServices Framework 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 image support and editing disabled before displaying the controller:
let imagePicker = UIImagePickerController() imagePicker.delegate = self imagePicker.sourceType = UIImagePickerControllerSourceType.photoLibrary imagePicker.mediaTypes = [kUTTypeImage as String] imagePicker.allowsEditing = false self.present(imagePicker, animated: true, 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:
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) { let mediaType = info[UIImagePickerControllerMediaType] as! NSString self.dismiss(animated: true, completion: nil) } func imagePickerControllerDidCancel(_ picker: UIImagePickerController) { self.dismiss(animated: true, 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:
let mediaType = info[UIImagePickerControllerMediaType] as! NSString if mediaType.isEqual(to: kUTTypeImage as String) { // Media is an image } else if mediaType.isEqual(to: kUTTypeMovie as String) { // Media is a video }
The original, unedited image selected or photographed by the user may be obtained from the info dictionary as follows:
let image = info[UIImagePickerControllerOriginalImage] as! UIImage
Assuming that editing was enabled on the image picker controller object, the edited version of the image may be accessed via the UImagePickerControllerEditedImage dictionary key:
let image = info[UIImagePickerControllerEditedImage] as! UIImage
If the media is a video, the URL of the recorded media may be accessed as follows:
let 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 AVPlayer and AVPlayerViewController classes as outlined in the chapter entitled iOS 10 Video Playback using AVPlayer and AVPlayerViewController.
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( UIImagePickerControllerSourceType.camera) { // Code here }
Similarly, to test for access to the camera roll:
if UIImagePickerController.isSourceTypeAvailable( UIImagePickerControllerSourceType.savedPhotosAlbum) { // Code here }
Finally, to check for support for photo libraries:
if UIImagePickerController.isSourceTypeAvailable( UIImagePickerControllerSourceType.photoLibrary) { // 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(ViewController.image(image:didFinishSavingWithError: contextInfo:)), nil)
To save a video:
if (UIVideoAtPathIsCompatibleWithSavedPhotosAlbum(videoPath)) { UISaveVideoAtPathToSavedPhotosAlbum(videoPath, self, #selector(ViewController.image(image:didFinishSavingWithError: contextInfo:)), nil) }
Last, but by no means least, is the didFinishSavingWithError method which will be called when the action is either complete or failed due to an error:
func image(image: UIImage, didFinishSavingWithError error: NSErrorPointer, contextInfo:UnsafeRawPointer) { if error != nil { // Report error to user } }
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 iOS application or select media from the device photo libraries. Now that the theory has been covered, the next chapter entitled An Example iOS 10 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 10 Event Kit to Create Date and Location Based Reminders | An Example iOS 10 iPhone Camera Application |