UIImagePickerController: Snapping and Saving a Photo
Good morning, code junkies! Time for another Swift lesson and today, we're going to cover allowing your users to snap a photo in-app and save that photo to their Photos Album. As always, you can download the starter project here and follow along, if you want. This one starts with a simple user interface that has a UIImageView and two buttons: Snap and Save. Your project should look something like this:
Once storyboard setup is complete, hook up an IBOutlet to the imageView and the saveButton and an IBAction to the snapButton and saveButton. Now that that's taken care of, we'll need to edit the info.plist to make sure the user's okay with us using the camera, the photo library, and adding images to the photo library. Open your info.plist and add three new keys (and values):
Privacy - Camera Usage Description (Please allow access to your camera!)
Privacy - Photo Library Additions Usage Description (Please allow me to save pictures to your library!)
Privacy - Photo Library Usage Description (Please allow access to your photo library!)
When you're done, your info.plist should look a little like this:
Now, let's dig into the fun stuff: the code!
Add an optional UIImage class variable, selectedImage and, then, to allow the user to snap a photo using their device's camera, you'll need to inherit from two protocols: UIImagePickerControllerDelegate and UINavigationControllerDelegate. These will allow you to display and dismiss the UIImagePickerController. Then, we'll need some way to display the UIImagePickerController, get the data from it, and dismiss it if the user cancels. I've done this within an extension of ViewController, as you can see below:Some things to note: Line 5 instantiates the UIImagePickerController and lines 6 - 21 handle the setup of said controller. It first sets wether the user can edit the image they either select or take and then checks to see whether the user's camera is available. If it is, it tells the controller to use the camera as the image's source, that the capture mode will be a photo (instead of a video), and that the source should default to the device's front-facing camera. If the camera isn't available, the controller instead opens the photo library for the user to pick an image from it. The setup of the controller is completely in your hands, but this is how I'm choosing to set it up, right now.
It's also important to note that the controller can not use your Mac's camera, thus, running the project in a simulator will always result in being able to only select from the photo library!
Whew, that was quite a task! Now, then, we've only got a little more code to write before we can start snapping and saving some images. In your snapPressed(_:) function, we'll add two lines: the first will set the outputLabel's text to an empty string and the second will call the displayImageController() function. Setting the outputLabel's text should be unnecessary, but we're going to set it, just in case.
Next, below your savePressed(_:) function create a new objective-c function called image(_ image: UIImage, didFinishSavingWithError error: Error?, contextInfo: UnsafeRawPointer). This is the function that tells your ViewController if the image saved properly, so, inside this function, safely unwrap the error and, if one exists, change the outputLabel's text, appropriately and return from the function. Otherwise, change the outputLabel's text to let the user know the image saved.
Finally, in your savePressed(_:) function, you'll need to safely unwrap the selectedImage variable you made earlier and then call UIImageWriteToSavedPhotosAlbum(_:_:_:_:), passing in the unwrapped image, self, the objective-c function you just created, and nil.
And you're all done! Your project should now look something like this:
If you build and run your project on the simulator and tap the Snap button, you'll be presented with the photo library for choosing an image. However, if you build and run your project on a live device, you'll see that you'll be able to snap a picture of something (or someone), like this one and save that image to your photos album! Pretty neat, huh?
Well, that's it for today's lesson. If you want to skip right to the good bits, you can download the finished project here. Either way, come join me next week for another dose of code!
P.S. Feel free to save and print that image (I've been told it's pretty good at scaring mice away)