Невозможно подстроить значение типа '[String: Any]' с индексом типа 'UIImagePickerController.InfoKey'

Я использую Apple Swift iOS Tutorial. Который выдает ошибку,

Невозможно добавить значение типа "[String: Any]" с индексом типа "UIImagePickerController.InfoKey".

Функция, которую они определили ниже.

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)
}

Я использую Xcode Version 10.0 beta 3, которая включает Swift 4.2.

Я хотел бы понять, как пройти через документы, чтобы понять, что могло измениться или сломаться.

Ответы

Ответ 1

Подпись метода изменилась в Swift 4.2

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

и вы должны написать

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

Вы можете сами определить такие терминологические изменения, прочитав документацию или комментируя весь метод, повторите первые несколько символов и используйте завершение кода.

Ответ 2

Я следую тому же учебнику, обновленный код выглядит следующим образом:

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)
}

Ответ 3

Используйте как это,

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

Ответ 4

Swift 5

В последней версии swift 4 или 5 метод делегата приведен ниже, он должен работать

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

И использовать,

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

}

Ответ 5

В Swift 4 и 5 вроде так:

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)
}

Ответ 6

Метод немного изменился в Swift 4.2.

Сначала инициализируйте эти две переменные:

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)
    }

}

Ответ 7

В Swift 4.2 вы можете написать функцию как:

    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
    }
}

Ответ 8

мой ViewController выглядит следующим образом. Я не могу нажать на изображение, чтобы выбрать другое изображение. Я также добавил конфиденциальность - использование библиотеки фотографий. Не могли бы вы мне помочь, пожалуйста?

//
//  ViewController.swift
//  FoodTracker
//
//  Created by Jakub Mikulastik on 09/06/2019.
//  Copyright © 2019 Jakub Mikulastik. All rights reserved.
//

import UIKit

class ViewController: UIViewController, UITextFieldDelegate, UIImagePickerControllerDelegate, UINavigationControllerDelegate {

    //MARK: Properties
    @IBOutlet weak var nameTextField: UITextField!
    @IBOutlet weak var mealNameLabel: UILabel!
    @IBOutlet weak var photoImageView: UIImageView!

    override func viewDidLoad() {
        super.viewDidLoad()

        // Handle the text fields user input through delegate callbacks.
        nameTextField.delegate = self
    }

    //MARK: UITextFieldDelegate
    func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        // Hide the keyboard.
        textField.resignFirstResponder()
        return true
    }
    func textFieldDidEndEditing(_ textField: UITextField) {
        mealNameLabel.text = textField.text
    }

    //MARK: UIImagePickerControllerDelegate
    func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
        // Dismiss the picker if the user canceled.
        dismiss(animated: true, completion: nil)
    }
    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)
    }

    //MARK: Actions
    @IBAction func selectImageFromPhotoLibrary(_ sender: UITapGestureRecognizer) {
        // Hide the keyboard.
        nameTextField.resignFirstResponder()

        // UIImagePickerController is a view controller that lets a user pick media from their photo library.
        let imagePickerController = UIImagePickerController()

        // Only allow photos to be picked, not taken.
        imagePickerController.sourceType = .photoLibrary

        // Make sure ViewController is notified when the user picks an image.
        imagePickerController.delegate = self
        present(imagePickerController, animated: true, completion: nil)
    }

    @IBAction func setDefaultLabelText(_ sender: UIButton) {
        mealNameLabel.text = "Default Text"
    }

}

Ответ 9

Я также следую за учебником. Он работает после изменения, как показано ниже.

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)
}

Я использую XCode 11 и Swift 5.