Accessing Camera and Photo Library in Swift 3

I was recently working on a project in which I wanted to store images in Firebase. I began digging into the Firebase documentation to try and see how I could upload images into their “Storage” feature and then pull those images down later in my app. However, in doing so, I realized that I didn’t even know how to allow a user to take a new photo or select one from their photo library! I started looking in to how to solve this problem and stumbled across an incredible resource at:

I implemented a lot from that lesson, but did a few things a different way. The code seems pretty intense at first but if you break it down line-by-line, it starts to make more sense.

For the purposes of this blog, I just created a simple, single-view app that displays a blank imageView, allows the user to add a picture from either their camera or their photo library, and update the imageView with the selected picture. There is actually a lot of setup to be done before we even get in to the code so I’m going to break things down step by step.

1. Import MobileCoreServices

Pretty simple. MobileCoreServices comes with the default libraries in Xcode so you don’t even need to use CocoaPods or Carthage. By importing it, you have access to methods and properties that we’ll use later.

2. Adopt the Correct Protocols

The two necessary protocols we need to adopt are UIImagePickerControllerDelegate and UINavigationControllerDelegate. They give us access to some necessary functions that we will use in both getting our camera/photo library to show up and in deciding what to do once we get an image.

3. Update Info.plist

This was something that was relatively new to me. The only time I’ve ever been in the plist before this was to allow my app to make API calls to http addresses and not just https (and to be honest, the person I was pair programming with at the time did everything in regards to that). So what is the plist? Well if you look at the top, you’ll see three headings: “Key”, “Type”, and “Value.” Knowing what we know about Swift, we can assume that this is a dictionary of sorts.

For our purposes, we want to request access to the user’s camera and their photo library. In order to do this, we simply go to the bottom of the list, hover over the last item, and click the “+” button. This pulls up a whole list of options for us to choose from. We are dealing with privacy so we’ll scroll down to the “Privacy” section and look for something related to the camera: “Privacy — Camera Usage Description.” Once we add that, we can add a message in the “value” section that will be displayed to the user, explaining what is going on. In this case, we can just type something like “This app requests access to your camera.” What this is going to do is display this message in a pre-generated alert controller as such:

We can do a similar process to allow access to the photo library — “Privacy — Photo Library Usage Description” and add whatever message you’d like.

4. Add a Bool Property to your ViewController

What’s the point of this Bool? Well it will tell us if the image we select is a new picture (just taken with our camera) or not (a picture selected from our photo library). This will come in handy later once we actually select an image to use.

5. Create UI and Add Outlets/Actions

Configure your UI however you’d like. In the case of the demo app, I just added an ImageView and a Button. We can then hook them up to our ViewController in the normal way:

Now we will have access to both the ImageView and what will happen when we press our “Add Picture” button.

6. Choose Whether to Take New Picture or Select From Photo Library

So we’ve gotten to step 6 of 7 and barely written any code! Like I said, a lot of set up involved. Let’s get into the code and breakdown what is going on here.

Looks like a lot, I know

At it’s base, all I’m doing is setting up an alertController (which are very easy to set up once you’ve practiced) that allows the user to select whether they want to use the camera or the photo library. For the both actions, all of the meaningful code happens in the closure at the end (where you see { (action) in …}).

First, we check to see if the source we want is available. In this case, we are looking for the camera, which is an enum property on UIImagePickerControllerSourceType. If it is available, we declare a constant called “imagePicker” and set it equal to a default UIImagePickerController. We then set its delegate to self (self being the instance of our View Controller), it’s sourceType to camera (again the source that we are looking for in this case), and its mediaType to kUTTypeImage, casted as a String.

Wait wait wait…what is that strange looking “kUTTypeImage”? Essentially, that means it is a still image and, actually, that is the default mediaType (so we don’t actually need this line of code — its just good to see what is going on). We’ll actually look at this later in code so it is good to see it here first.

Next, we set allowsEditing to false because in this case, we don’t want the user to be able to edit the image that take. We then present the imagePicker and set our Bool property to true, since this is a new picture.

We can repeat essentially the same process for the cameraRollAction except the sourceType is “photoLibrary.”

If you mess around a little bit more, you’ll see that there’s actually another option called “savedPhotosAlbum.” What’s the difference? Well from my extensive research (I switched them up in code and ran the project using different combinations of “photoLibrary” and “savedPhotosAlbum”), either one is fine to use for the .isSourceTypeAvailable method. However, if you set your imagePicker.sourceType to photoLibrary, you’ll get all of the albums in your photo library whereas is you set it to savedPhotosAlbum, you get brought directly into your “Moments” folder. There may be a way to change which folder you go in to in your own phone settings, but for the purposes of this blog, just know that photoLibrary brings you to your entire library and savedPhotosAlbum brings you to just one album. The other difference is that our Bool property is set to false, since this is not a new image.

After that, we just add both of our actions to our alert and present it:

If we run the app, we should see our alertController get displayed and we’re able to access both the camera and our photo library:

7. Implement What Happens When an Image is Selected

There are two delegate methods that we need (they aren’t required but you really should) to set up in order to properly finish up this app: didFinishPickingMediaWithInfo and imagePickerControllerDidCancel. As you can probably guess from the names, the first one decides what happens when an image is picked and the second one decides what happens when a user decides not to pick an image and instead presses “cancel.” We’ll go through them one by one:

The first thing to notice is that in the function parameters, there is one called “info” which we can see is a dictionary. If we dig a little deeper into the documentation, we’ll see that the keys for this dictionary are different types (UIImagePickerControllerMediaType, UIImagePickerControllerOriginalImage, UIImagePickerControllerEditedImage, etc). You can bet that we’ll want access to some of the values at those keys. So first, we declare a constant called “mediaType” and set it equal to the value at key “UIImagePickerControllerMediaType” and cast it as an NSString. If that mediaType is equal to kUTTypeImage as String (which we know it is since that’s what we set the mediaType to when we set up our imagePicker), then we’ll do the following:

  1. declare a new constant called “image” which accesses the value at the “UIImagePickerControllerOriginalImage” (since we didn’t edit the image) and casts it as a UIImage
  2. Set this image equal to the image of the imageView on our ViewController
  3. If it is a new image (from the camera), we store it in our saved photos using the “UIImageWriteToSavedPhotosAlbum” method. (You’ll notice that in this method, we call on another function called “imageError.” Remember this because I’ll explain it later!

We can then dismiss the view and return back to our normal ViewController, which we’ll notice has been updated with the image we selected.

We then need to implement the second function:

Wow. Much simpler. Basically, if the user presses cancel, just dismiss the view.

I mentioned above about another function we call on when saving the image. This is useful to write because if, for some reason, the image cannot be saved, the user should know. Let’s take a look at it:

Where does this even come from? Well if you command+click into the UIImagePickerControllerDelegate, you’ll see down at the bottom that they have it written as a comment. They tell you how to set up the method signature (I called it “imageError” instead of “image” just for the sake of readability). It looks like a lot, but, once again, it’s just an alert controller that gets displayed if there is an error (error != nil). It just tells the user that the image could not be saved.

And there you have it — an app that allows the user to access the camera and photo library to select an image and update an imageView with that image. I’ll admit that the code is kind of dense, but with repetition and focus on what every line is doing, it becomes easier to understand.

iOS Developer