Accessing and using the camera the simple way

We will focus on building a nice login screen for a fictional app named ArtApp. This application is an Augmented Reality (AR) application that focuses on art. The login form fields will be positioned at the center of the screen. The camera will provide a background, and as the user moves their phone, we'll make the login field move around a bit. This effect will look similar to the iOS wallpaper parallax effect you might have noticed while using your iPhone. We'll use location data to provide a fictional indication of how many pieces of Augmented Reality art are near the user's current location. Before you get started, create a new single page app named ArtApp; you don't have to include Core Data or unit tests for this application.

The application we will build in this chapter requires you to test it on a real device. The iOS simulator has limited support for GPS, but it doesn't have a camera or motion sensor access. Make sure that you have a device that runs iOS 11 nearby.

There are different ways to access the camera in iOS. A lot of applications don't need direct access to the camera. An example of a situation where you don't need this direct access is when a user uploads a profile picture. Your end goal in this case is to obtain a photo. This photo can be provided either from the camera roll or from the camera itself. In these situations, the UIImagePickerController class is ideal.

This class is the easiest way for developers to access the camera as all of the controls and interface elements are already implemented. The UIImagePickerController enables users to take a photo, switch to the front-facing camera, and more. In short, it provides access to all controls a user may expect from the default camera app. Once a photo has been taken, it is passed on to your application so you can process it as desired.

If you simply want to enable your user to take a picture or shoot a video that is used in your app, UIImagePickerController is very likely to be the tool you need. Let's take a quick look at how to use this class in your app. Note that the following code does not work as you might want it to in the iOS simulator because it does not have access to the camera:

 

let imagePicker = UIImagePickerController() 

if UIImagePickerController.isSourceTypeAvailable(.camera) {
imagePicker.sourceType = .camera
imagePicker.cameraCaptureMode = .photo
} else {
imagePicker.sourceType = .photoLibrary
}

present(imagePicker, animated: true, completion: nil)

The preceding code will present the user with a camera interface, if possible. If the camera is not available, the users are presented with an image picker that shows their photo library.

This example isn't very useful because it does not yet obtain a reference to the selected photo. Once a user has selected a photo, the UIImagePickerController notifies its delegate about the selection the user has made. This means that in order to be notified about the user's choice, you must implement and assign a delegate for UIImagePickerController. The method you should implement to receive the selected photo is imagePickerController(_:didFinishPickingMediaWithInfo:).

The chosen image is available in the info dictionary that's passed to the delegate method. An implementation of this delegate method could be the following:

extension ViewController: UIImagePickerControllerDelegate { 
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {

guard let image = info[UIImagePickerControllerOriginalImage]
else { return }

anImageView.image = image
}
}

The preceding snippet extracts the selected image from the info dictionary and sets it as the image for an image view. You can configure UIImagePickerController to allow the user to crop an image they selected. To do this, you will need to set the image picker controller's allowsEditing property to true. If you do this, the cropped image is available through the UIImagePickerControllerCroppedImage key in the info dictionary that is passed to imagePickerController(_:didFinishPickingMediaWithInfo:). For an exhaustive list of keys that are passed to the info dictionary, refer to the UIImagePickerController page on Editing Information Keys in Apple's documentation.

Although the preceding approach is very convenient if all you need to do is access an image from the user's library, or if you want them to supply an image through the camera, it's not the way to go if you need to read input from the camera in real time. The login screen we're going to build for ArtApp should show a real-time camera feed as a background. This means we need direct access to the camera.