An Example Swift iOS 8 iPhone Camera Application
Previous | Table of Contents | Next |
Accessing the iOS 8 Camera and Photo Library in Swift | iOS 8 Video Playback using AVPlayer and AVPlayerViewController |
<google>BUY_IOS8</google>
In the chapter entitled Accessing the iOS 8 Camera and Photo Library in Swift we looked in some detail at the steps necessary to provide access to the iOS camera and photo libraries in an iOS 8 application. The purpose of this chapter is to build on this knowledge by working through an example iOS application designed to access the device’s camera and photo libraries.
An Overview of the Application
The application user interface for this example will consist of an image view and a toolbar containing two buttons. When touched by the user, the first button will display the camera to the user and allow a photograph to be taken which will subsequently be displayed in the image view. The second button will provide access to the camera roll where the user may select an existing photo image. In the case of a new image taken with the camera, this will be saved to the camera roll.
Since we will be covering the playback of video in the next chapter (iOS 8 Video Playback using AVPlayer and AVPlayerViewController) the camera roll and camera will be restricted to still images in this example. The addition of video support to this application is left as an exercise for the reader.
Creating the Camera Project
Begin the project by launching Xcode and creating a new Universal iOS application project named Camera using the Single View Application template with the Swift language option selected.
Designing the User Interface
The next step in this tutorial is to design the user interface. This is a very simple user interface consisting of an image view, a toolbar and two bar button items. Select the Main.storyboard file and drag and drop components from the Object Library (View -> Utilities -> Show Object Library) onto the view. Position and size the components and set the text on the bar button items so that the user interface resembles Figure 86-1.
Figure 86-1
In terms of Auto Layout constraints, begin by selecting the toolbar view and clicking on the Pin menu in the toolbar located in the lower right hand corner of the storyboard canvas and establish Spacing to nearest neighbor constraints on the bottom and two side edges of the view with the Constrain to margins option switched off.
Next, select the Image View object and, once again using the Pin menu, establish Spacing to nearest neighbor constraints on all four sides of the view, this time with the Constrain to margins option enabled.
Finally, with the Image View still selected, display the Attributes Inspector panel and change the Mode attribute to Aspect Fit.
Select the image view object in the view canvas, display the Assistant Editor panel. Ctrl-click on the image view object and drag to a position just below the class declaration line in the Assistant Editor. Release the line, and, in the resulting connection dialog, establish an outlet connection named imageView.
With the Assistant Editor still visible, establish action connections for the two buttons to methods named useCamera and useCameraRoll respectively (keeping mind that it may be necessary to click twice on each button to select it since the first click will typically select the toolbar parent object).
Close the Assistant Editor, select the ViewController.swift file and modify it further to add import and delegate protocol declarations together with a Boolean property declaration that will be required later in the chapter:
import UIKit import MobileCoreServices class ViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate { @IBOutlet weak var imageView: UIImageView! var newMedia: Bool? . .
Implementing the Action Methods
The useCamera and useCameraRoll action methods now need to be implemented. The useCamera method first needs to check that the device on which the application is running has a camera. It then needs to create a UIImagePickerController instance, assign the cameraViewController as the delegate for the object and define the media source as the camera. Since we do not plan on handling videos the supported media types property is set to images only. Finally, the camera interface will be displayed. The last task is to set the newMedia flag to true to indicate that the image is new and is not an existing image from the camera roll. Bringing all these requirements together gives us the following useCamera method:
@IBAction func useCamera(sender: AnyObject) { if UIImagePickerController.isSourceTypeAvailable( UIImagePickerControllerSourceType.Camera) { let imagePicker = UIImagePickerController() imagePicker.delegate = self imagePicker.sourceType = UIImagePickerControllerSourceType.Camera imagePicker.mediaTypes = [kUTTypeImage as NSString] imagePicker.allowsEditing = false self.presentViewController(imagePicker, animated: true, completion: nil) newMedia = true } }
<google>BUY_IOS8</google> The useCameraRoll method is remarkably similar to the previous method with the exception that the source of the image is declared to be UIImagePickerControllerSourceType.PhotoLibrary and the newMedia flag is set to false (since the photo is already in the library we don’t need to save it again):
@IBAction func useCameraRoll(sender: AnyObject) { if UIImagePickerController.isSourceTypeAvailable( UIImagePickerControllerSourceType.SavedPhotosAlbum) { let imagePicker = UIImagePickerController() imagePicker.delegate = self imagePicker.sourceType = UIImagePickerControllerSourceType.PhotoLibrary imagePicker.mediaTypes = [kUTTypeImage as NSString] imagePicker.allowsEditing = false self.presentViewController(imagePicker, animated: true, completion: nil) newMedia = false } }
Writing the Delegate Methods
As described in Accessing the iOS 8 Camera and Photo Library in Swift, in order to fully implement an instance of the image picker controller delegate protocol it is necessary to implement some delegate methods. The most important method is didFinishPickingMediaWithInfo which is called when the user has finished taking or selecting an image. The code for this method in our example reads as follows:
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [NSObject : AnyObject]) { let mediaType = info[UIImagePickerControllerMediaType] as! String self.dismissViewControllerAnimated(true, completion: nil) if mediaType.isEqualToString(kUTTypeImage as! String) { let image = info[UIImagePickerControllerOriginalImage] as! UIImage imageView.image = image if (newMedia == true) { UIImageWriteToSavedPhotosAlbum(image, self, "image:didFinishSavingWithError:contextInfo:", nil) } else if mediaType.isEqualToString(kUTTypeMovie as! String) { // Code to support video here } } } func image(image: UIImage, didFinishSavingWithError error: NSErrorPointer, contextInfo:UnsafePointer<Void>) { if error != nil { let alert = UIAlertController(title: "Save Failed", message: "Failed to save image", preferredStyle: UIAlertControllerStyle.Alert) let cancelAction = UIAlertAction(title: "OK", style: .Cancel, handler: nil) alert.addAction(cancelAction) self.presentViewController(alert, animated: true, completion: nil) } }
The code in this delegate method dismisses the image picker view and identifies the type of media passed from the image picker controller. If it is an image it is displayed on the view image object of the user interface. If this is a new image it is saved to the camera roll. The finishedSavingWithError method is configured to be called when the save operation is complete. If an error occurred it is reported to the user via an alert box.
It is also necessary to implement the imagePickerControllerDidCancel delegate method which is called if the user cancels the image picker session without taking a picture or making an image selection. In most cases all this method needs to do is dismiss the image picker:
func imagePickerControllerDidCancel(picker: UIImagePickerController) { self.dismissViewControllerAnimated(true, completion: nil) }
Building and Running the Application
In order to experience the full functionality of this application it will be necessary to install it on a physical device with a camera. Steps on performing this are covered in Testing Apps on iOS 8 Devices with Xcode 6.
Assuming certificates and provisioning are configured, click on the Xcode run button to launch the application. Once the application loads, select the Camera button to launch the camera interface.
Figure 86-2
Once the picture has been taken and selected for use in the application, it will appear in the image view object of our application user interface.
Selecting the Camera Roll button will provide access to the camera roll and photo stream on the device where an image selection can be made:
Figure 86-3
<google>BUY_IOS8</google>
Previous | Table of Contents | Next |
Accessing the iOS 8 Camera and Photo Library in Swift | iOS 8 Video Playback using AVPlayer and AVPlayerViewController |