Take a Still Photo:
classes UIImagePickerController and UIImagePickerControllerDelegate

The resulting image is a 2592 × 1936 still life with Rema patch kit:

A UIImagePickerController is a view controller whose view lets you capture a still image or video from the camera, or from the camera roll or photo library. The UIImagePickerController should be presented modally, because eventually the user will finish using the camera and will want to go back to where they were before. The touchUpInside method of the main ViewController slides the UIImagePickerController up, and the imagePickerController(_:didFinishPickingMediaWithInfo:) method of the ViewController slides the UIImagePickerController back down.

When you take a photo and decide to accept it (by pressing “Use Photo” as opposed to “Retake”), the imagePickerController(_:didFinishPickingMediaWithInfo:) method of the UIImagePickerController’s delegate is automatically called. Our ViewController is the delegate. The delegate must adopt two protocols: UIImagePickerControllerDelegate and UINavigationControllerDelegate.

The result of all of this activity is a UIImage object. Here are three things we can do with it:

  1. Print it in the drawRect(_:) method of a view, as in America.
  2. Insert it into a UIImageView object, as in Puzzle and StarWars.
  3. Save it in the Camera roll, as in the present app.

Source code in Still.zip

  1. AppDelegate.swift: unchanged.
  2. ViewController.swift. This is the main view controller. It is temporarily covered by the UIImagePickerController.
  3. View.swift.
  4. Info.plist. The “Required Device Capabilities” (UIRequiredDeviceCapabilities) property already exists. I added still-camera to it.

Create the project

Select the Info.plist file in the Supporting Files folder in the Xcode Project Navigator. Click the open triangle in front of the Required Device Capabilities property. It should already contain the capability armv7. Add the capability still-camera.

Run the project

The iOS Simulator has no camera, so the following output is produced by the first if in the init method of the ViewController.

Camera not available on iPhone Simulator.
To run this app on a real device, select your device in the upper left corner of Xcode.

Open the Settings app on the device.
Settings → Privacy → Camera
Apps that have requested access to the camera will appear here.

To take a screenshot, pull down the Xcode Window menu.
Window → Devices → Device Information
Take Screenshot

After you press “Use Photo” and return to the starting button, can you take another photo?

Output from print

I don’t know why we got the “snapshotting” warning.

2014-12-14 10:09:15.984 Still[836:103445] Snapshotting a view that has not been rendered results in an empty snapshot.
Ensure your view has been rendered at least once before snapshotting or snapshot after screen updates.

dimensions in pixels = 2592 × 1936

image written: URL = assets-library://asset/asset.JPG?id=0EFE0C32-1610-45A9-86AE-69B2564BC88E&ext=JPG, error = nil

Things to try

  1. In addition to printing the PixelXDimension and PixelYDimension as Int, print the DateTimeOriginal and LensModel as String.

  2. Take a video instead of a still. Make the following changes.
    1. In the Required Device Capabilities property in the Info.plist file in the Supporting Files folder in the Xcode Project Navigator, change the still-camera capability to video-camera. Add the microphone capability.
    2. In the init method of class View, change the title of the button to “Shoot a video”.
    3. In the init method of class ViewController, change each occurrence of kUTTypeImage to kUTTypeMovie. Change UIImagePickerControllerCameraCaptureMode.Photo to UIImagePickerControllerCameraCaptureMode.Video.
    4. Change the imagePickerController(_:didFinishPickingMediaWithInfo:) method of the ViewController to the following.
      	//This method of the UIImagePickerControllerDelegate is called
      	//when the user presses the camera's "Use Video" button.
      
      	func imagePickerController(picker: UIImagePickerController,
      		didFinishPickingMediaWithInfo info: [NSObject: AnyObject]) {
      
      		//If we captured a video,
      		let mediaType: CFString? = info[UIImagePickerControllerMediaType] as CFString?;
      		if mediaType != nil && mediaType! == kUTTypeMovie {
      
      			//Get the URL that leads to the video file.
      			let url: NSURL? = info[UIImagePickerControllerMediaURL] as NSURL?
      			if url != nil {
      				print("url! = \(url!)");
      				print("url!.relativePath! = \(url!.relativePath!)");
      
      				//Save the video file in the Camera Roll.
      				if UIVideoAtPathIsCompatibleWithSavedPhotosAlbum(url!.relativePath!) {
      					UISaveVideoAtPathToSavedPhotosAlbum(url!.relativePath!, nil, nil, nil);
      				} else {
      					print("Cannot save video to Camera Roll.");
      				}
      			}
      		}
      
      		dismissViewControllerAnimated(true, completion: nil);
      	}
      

      “Still” would like to access the microphone.
      Settings → Privacy → Microphone

      2014-12-14 16:33:49.135 Still[1282:145234] Snapshotting a view that has not been rendered results in an empty snapshot.
      Ensure your view has been rendered at least once before snapshotting or snapshot after screen updates.
      
      url! = file:///private/var/mobile/Containers/Data/Application/30858263-DD29-4EB6-9DCD-C2C639DCDAAE/tmp/capture-T0x14e53d80.tmp.mvEj6p/capturedvideo.MOV
      
      url!.relativePath! = /private/var/mobile/Containers/Data/Application/30858263-DD29-4EB6-9DCD-C2C639DCDAAE/tmp/capture-T0x14e53d80.tmp.mvEj6p/capturedvideo.MOV
      
      2014-12-14 16:33:58.645 Still[1282:145234] -[UIWindow endDisablingInterfaceAutorotationAnimated:] called on
      <UIWindow: 0x14da3990; frame = (0 0; 320 568); gestureRecognizers = <NSArray: 0x14d9fc90>; layer = <UIWindowLayer: 0x14d9b570>>
      without matching -beginDisablingInterfaceAutorotation. Ignoring.
      

  3. Shoot a silent movie: change kUTTypeMovie to kUTTypeVideo.

  4. Can you spell out S.O.S. in Morse code with the flashbulb?

  5. Get a list of all the photos and videos in the Camera Roll.