Cannot subscript a value of type '[String : Any]' with an index of type 'UIImagePickerController.InfoKey'

IosSwiftUiimagepickercontroller

Ios Problem Overview


I'm using Apple's Swift iOS Tutorial. Which is throwing an error,

> Cannot subscript a value of type '[String : Any]' with an index of type 'UIImagePickerController.InfoKey'

The function they defined is below.

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

    // The info dictionary may contain multiple representations of the image. You want to use the original.
    guard let selectedImage = info[UIImagePickerControllerOriginalImage] as? UIImage else {
        fatalError("Expected a dictionary containing an image, but was provided the following: \(info)")
    }

    // Set photoImageView to display the selected image.
    photoImageView.image = selectedImage

    // Dismiss the picker.
    dismiss(animated: true, completion: nil)
}

I'm using Xcode Version 10.0 beta 3, which includes Swift 4.2.

I'd like to understand how to traverse the docs to understand what might have changed or broken.

Ios Solutions


Solution 1 - Ios

The signature of the method has changed in Swift 4.2

func imagePickerController(_ picker: UIImagePickerController, 
  didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any])

and you have to write

guard let selectedImage = info[.originalImage] as? UIImage else {
    fatalError("Expected a dictionary containing an image, but was provided the following: \(info)")
}

You can figure out such terminology changes yourself by reading the documentation or by commenting out the entire method, retype the first few characters and use code completion.

Solution 2 - Ios

I'm following also the same tutorial, the updated code looks like this:

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
    
    // The info dictionary may contain multiple representations of the image. You want to use the original.
    guard let selectedImage = info[.originalImage] as? UIImage else {
        fatalError("Expected a dictionary containing an image, but was provided the following: \(info)")
    }
    
    // Set photoImageView to display the selected image.
    photoImageView.image = selectedImage
    
    // Dismiss the picker.
    dismiss(animated: true, completion: nil)
}

Solution 3 - Ios

Swift 5

In latest version of swift 4 or 5 the delegate method is given below, it should work

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
    // Code here
}

And use,

guard let selectedImage = info[.editedImage] as? UIImage else {

}



func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
    guard let selectedImage = info[.editedImage] as? UIImage else {

    }
}

Solution 4 - Ios

Use like this,

guard let selectedImage = info[UIImagePickerController.InfoKey.originalImage.rawValue] as? UIImage else {
        fatalError("Expected a dictionary containing an image, but was provided the following: \(info)")
}

Solution 5 - Ios

In Swift 4 and 5 like so:

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
    
    guard let selectedImage = info[.editedImage] as? UIImage else {
        fatalError("Expected a dictionary containing an image, but was provided the following: \(info)")
    }
    
    self.myImageView.image = selectedImage
    
    picker.dismiss(animated: true, completion: nil)
}

Solution 6 - Ios

I am also following the tutorial. It is working after changing as below.

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
    
    // The info dictionary may contain multiple representations of the image. You want to use the original.
    guard let selectedImage = info[.originalImage] as? UIImage
        else {
        fatalError("Expected a dictionary containing an image, but was provided the following: \(info)")
    }
    
    // Set photoImageView to display the selected image.
    photoImageView.image = selectedImage
    
    // Dismiss the picker.
    dismiss(animated: true, completion: nil)
}

I am using XCode 11 and Swift 5.

Solution 7 - Ios

Method has been changed a little bit in Swift 4.2.

First initialise these two variables:

var imagePicker = UIImagePickerController()
var pickedImageProduct = UIImage()

extension yourViewController: UIImagePickerControllerDelegate,UINavigationControllerDelegate{
//create an IBAction to access Camera
    @IBAction func accessCameraBtn(_ sender: UIButton) {
        imagePicker.delegate = self
        imagePicker.sourceType = UIImagePickerController.SourceType.camera
        self.present(imagePicker, animated: true, completion: nil)
    }
//create an IBAction to access Gallery
    @IBAction func accessGalleryBtn(_ sender: UIButton) {
        imagePicker.delegate = self
        imagePicker.sourceType = UIImagePickerController.SourceType.photoLibrary
        self.present(imagePicker, animated: true, completion: nil)
    }
//Final step put this Delegate    
    func imagePickerController(_ picker: UIImagePickerController,
                               didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
        
        guard let selectedImage = info[.originalImage] as? UIImage else {
           Print("Error: \(info)")
        }
        
            pickedImageProduct = selectedImage
        
        dismiss(animated: true, completion: nil)
     }
    func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
        
        dismiss(animated: true, completion: nil)
    }
    
}

Solution 8 - Ios

In Swift 4.2 you can write the function as:

    func photoLib()
    {
        //opens Photo Library, call the function in a @IBAction func
        let myPickerController = UIImagePickerController()
        myPickerController.delegate = self;
        myPickerController.sourceType = 
        UIImagePickerController.SourceType.photoLibrary
        myPickerController.allowsEditing = true
        present(myPickerController, animated: true)
    }


    func imagePickerController(_ picker: UIImagePickerController, 
    didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
    picker.dismiss(animated: true)
    
    guard let image = info[.editedImage] as? UIImage else {
        print("No image found")
        photoLabel.text = "Photo Not Found"
        return
    }
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestiondrobatiView Question on Stackoverflow
Solution 1 - IosvadianView Answer on Stackoverflow
Solution 2 - IosedymerchkView Answer on Stackoverflow
Solution 3 - IosSaranjithView Answer on Stackoverflow
Solution 4 - IosSureshkumar LinganathanView Answer on Stackoverflow
Solution 5 - IosMr TView Answer on Stackoverflow
Solution 6 - IosSaju KSView Answer on Stackoverflow
Solution 7 - IosAkbar KhanView Answer on Stackoverflow
Solution 8 - IosPrakhar Prakash BhardwajView Answer on Stackoverflow