Search code examples
iosswiftswift3uiimagepickercontroller

imagePickerController crashes when fetching photos from camera. From photo library works fine. Why?


In my swift app I'm allowing user to add a photo - either from camera or from photo library. He has a choice:

@IBAction func captureImage(_ sender: AnyObject) {

    let imageFromSource = UIImagePickerController()
    imageFromSource.delegate = self
    imageFromSource.allowsEditing = false

    let alertController = UIAlertController(
        title: "What exactly do you want to do?",
        message: "Choose your action.",
        preferredStyle: .actionSheet)

    let selectPictureAction = UIAlertAction(
        title: "Choose image from gallery",
        style: .default) { (action) -> Void in

            imageFromSource.sourceType = UIImagePickerControllerSourceType.photoLibrary
            self.present(imageFromSource, animated: true, completion: nil)
    }
    alertController.addAction(selectPictureAction)

    let captureFromCamera = UIAlertAction(
    title: "Capture photo from camera",
    style: .default) { (action) -> Void in
        imageFromSource.sourceType = UIImagePickerControllerSourceType.camera   
        self.present(imageFromSource, animated: true, completion: nil)   
    }
    alertController.addAction(captureFromCamera)
}

and then I have a function:

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {

    let imageUrl          = info[UIImagePickerControllerReferenceURL] as! NSURL
    let imageName         = imageUrl.lastPathComponent
    let documentDirectory = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first!
    let photoURL          = NSURL(fileURLWithPath: documentDirectory)
    let localPath         = photoURL.appendingPathComponent(imageName!)
    let image             = info[UIImagePickerControllerOriginalImage]as! UIImage
    let data              = UIImagePNGRepresentation(image)
    do
    {
        try data?.write(to: localPath!, options: Data.WritingOptions.atomic)
    }
    catch
    {
        // Catch exception here and act accordingly

    }
    self.dismiss(animated: true, completion: {})

    imageView.image = image
    .
    .
    .

When user chooses image from gallery - everything works fine, but when user takes a photo - my app crashes on this line:

let imageUrl          = info[UIImagePickerControllerReferenceURL] as! NSURL

with an error:

fatal error: unexpectedly found nil while unwrapping an Optional value

I need this imageUrl to display the image later on imageView - so how can I handle the camera output here?


Solution

  • let imageUrl = info[UIImagePickerControllerReferenceURL] as! NSURL
    

    I need this imageUrl to display the image later on imageView - so how can I handle the camera output here?

    You are wrong. You do not need it, and it makes no sense to ask for it, as this image, by definition, is not in the photo library — it has no reference URL.

    The key you want in this situation is UIImagePickerControllerOriginalImage.

    (Indeed, in all probability you should never have been using UIImagePickerControllerReferenceURL for anything, since you are given the UIImagePickerControllerOriginalImage in both cases. That is the image you are expected to use if your purpose is display in an image view.)