Accessing the iOS 17 Camera and Photo Library

The iOS SDK provides access to both the camera device and photo library through the UIImagePickerController class. It allows videos and photographs to be taken from within an app 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 using the UIImagePickerController class before working through the step-by-step creation of an example app in An iOS 17 Camera App Tutorial.

The UIImagePickerController Class

The ultimate purpose of the UIImagePickerController class is to provide apps with either an image or video. It achieves this task by providing users access to the device’s camera roll and photo libraries. In the case of the camera, the user can either take a photo or record a video depending on the device’s capabilities and the app’s configuration of the UIImagePickerController object. Regarding camera roll and library access, the object provides the app with the existing image or video the user selects. In addition, the controller also allows new photos and videos created within the app to be saved to the library.

Creating and Configuring a UIImagePickerController Instance

When using 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 acceptable to the app must also be defined (photos, videos, or both). Finally, another configuration option defines whether the user can edit a photo once it has been taken and before it is passed to the app.

The source of the media is defined by setting the sourceType property of the UIImagePickerController object to one of the three supported types:

 

You are reading a sample chapter from Building iOS 17 Apps using Xcode Storyboards.

Buy the full book now in eBook or Print format.

The full book contains 96 chapters and 760 pages of in-depth information.

Learn more.

Preview  Buy eBook  Buy Print

 

  • UIImagePickerController.SourceType.camera
  • UIImagePickerController.SourceType.savedPhotosAlbum
  • UIImagePickerController.SourceType.photoLibrary

The types of media acceptable to the app 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 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 app 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 = UIImagePickerController.SourceType.photoLibrary
imagePicker.mediaTypes = [kUTTypeImage as String]
imagePicker.allowsEditing = false

self.present(imagePicker, animated: true, completion: nil)Code language: Swift (swift)

It should be noted that the above code also configured the current class as the delegate for the UIImagePickerController instance. This delegate is 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 app essentially hands control to that object. That being the case, the controller needs some way to notify the app 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. For example, when the user has selected or created media, the didFinishPickingMediaWithInfo method is called and passed an NSDictionary object containing the media and associated data. If 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:

 

You are reading a sample chapter from Building iOS 17 Apps using Xcode Storyboards.

Buy the full book now in eBook or Print format.

The full book contains 96 chapters and 760 pages of in-depth information.

Learn more.

Preview  Buy eBook  Buy Print

 

func imagePickerController(_ picker: UIImagePickerController, 
didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
    let mediaType = info[UIImagePickerController.InfoKey.mediaType] 
                                   as! NSString

    self.dismiss(animated: true, completion: nil)
}

func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
    self.dismiss(animated: true, completion: nil)
}Code language: Swift (swift)

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[UIImagePickerController.InfoKey.mediaType] 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

}Code language: Swift (swift)

The original, unedited image selected or photographed by the user may be obtained from the info dictionary as follows:

let image = info[UIImagePickerController.InfoKey.originalImage] as! UIImageCode language: Swift (swift)

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[UIImagePickerController.InfoKey.editedImage] as! UIImageCode language: Swift (swift)

If the media is a video, the URL of the recorded media may be accessed as follows:

let url = info[UIImagePickerController.InfoKey.mediaURL]Code language: Swift (swift)

Once the image or video URL has been obtained, the app 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 later in the chapter entitled iOS 17 Video Playback using AVPlayer and AVPlayerViewController.

 

You are reading a sample chapter from Building iOS 17 Apps using Xcode Storyboards.

Buy the full book now in eBook or Print format.

The full book contains 96 chapters and 760 pages of in-depth information.

Learn more.

Preview  Buy eBook  Buy Print

 

Detecting Device Capabilities

Not all iOS devices provide the same functionality. For example, iPhone models before the 3GS model do not support video recording. In addition, 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(
		UIImagePickerController.SourceType.camera) {
	// Code here
}Code language: Swift (swift)

Similarly, to test for access to the camera roll:

if UIImagePickerController.isSourceTypeAvailable(
		UIImagePickerController.SourceType.savedPhotosAlbum) {
	// Code here
}Code language: Swift (swift)

Finally, to check for support for photo libraries:

if UIImagePickerController.isSourceTypeAvailable(
		UIImagePickerController.SourceType.photoLibrary) {
	// Code here
}Code language: Swift (swift)

Saving Movies and Images

Once a video or photo created by the user using the camera is handed off to the app, it is then the responsibility of the app 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 app continues to run. When the action is complete, a specified method is called to notify the app of the success or otherwise of the operation. To save an image:

UIImageWriteToSavedPhotosAlbum(image, self,
                #selector(ViewController.image(image:didFinishSavingWithError:
					contextInfo:)), nil)Code language: Swift (swift)

To save a video:

 

You are reading a sample chapter from Building iOS 17 Apps using Xcode Storyboards.

Buy the full book now in eBook or Print format.

The full book contains 96 chapters and 760 pages of in-depth information.

Learn more.

Preview  Buy eBook  Buy Print

 

if (UIVideoAtPathIsCompatibleWithSavedPhotosAlbum(videoPath))
{
     UISaveVideoAtPathToSavedPhotosAlbum(videoPath, self,
        #selector(ViewController.image(image:didFinishSavingWithError:
			contextInfo:)), nil)
}Code language: Swift (swift)

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 the user
    }
}Code language: Swift (swift)

Summary

In this chapter, we have provided an overview of the UIImagePickerController and looked at how this class can allow a user to take a picture or record video from within an iOS app or select media from the device photo libraries. Now that the theory has been covered, the next chapter, entitled An iOS 17 Camera App Tutorial, will work through the development of an example app designed to implement the theory covered in this chapter.


Categories