Проблемы с разрешением захвата фото в iOS 11

Итак, вот моя проблема. Я пытаюсь создать экран, в котором есть UIImageView и UIButton. Когда пользователь нажимает кнопку, открывается приложение камеры, вы делаете снимок, и если вы нажмете "Использовать фотографию" в приложении "Камера", вы вернетесь на экран своего приложения, и фотография будет помещена в UIImageView, о котором я упоминал ранее.

Что происходит до сих пор, так это то, что когда я нажимаю кнопку "Использовать фотографию", изображение правильно помещается в мой UIImageView, но затем приложение вылетает со следующей ошибкой:

Это приложение потерпело крах, поскольку оно попыталось получить доступ к конфиденциальным данным без описания использования. Приложение Info.plist должно содержать ключ NSPhotoLibraryAddUsageDescription со строковым значением, объясняющим пользователю, как приложение использует эти данные.

Что я сделал до сих пор:

  • Размещенный ключ "Конфиденциальность - описание использования библиотеки фотографий" со значением "$ (PRODUCT_NAME) использует библиотеку, чтобы обрабатывать сделанные вами фотографии". в файле Info.plist(также проверено, как оно написано в форме источника, и оно исправлено в соответствии с Документацией разработчика Apple).

  • Также поместил ключ "Конфиденциальность - описание использования камеры" со значением "$ (PRODUCT_NAME) использует" Камеры "в файле Info.plist.

  • Проверено в разделе "TARGETS → - > Info- > Пользовательские свойства целевого объекта iOS" и две пары "ключ/значение", упомянутые в шагах 1 и 2.

Я покажу вам свой код:

import UIKit
import Vision
import MobileCoreServices
import AVFoundation
import Photos

class ViewController: UIViewController, UIImagePickerControllerDelegate, 
UINavigationControllerDelegate {

var newMedia: Bool?

@IBAction func captureImageButtonPressed(_ sender: Any) {
    //let imageName : String = "dolphin"
    //randomImageView.image = UIImage.init(named:imageName)

    if UIImagePickerController.isSourceTypeAvailable(
        UIImagePickerControllerSourceType.camera) {

        let imagePicker = UIImagePickerController()

        imagePicker.delegate = self
        imagePicker.sourceType =
            UIImagePickerControllerSourceType.camera
        imagePicker.mediaTypes = [kUTTypeImage as String]
        imagePicker.allowsEditing = false

        self.present(imagePicker, animated: true,
                     completion: nil)
        newMedia = true
    }
}

@IBAction func classifyButtonPressed(_ sender: UIButton) {
    performVisionRequest()
}
@IBOutlet weak var randomImageView: UIImageView!
@IBOutlet weak var classificationLabel: UILabel!

override func viewDidLoad() {
    super.viewDidLoad()
}

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
}

func performVisionRequest() {
    let start = DispatchTime.now()
    let model = Resnet50()
    let request = VNImageRequestHandler(cgImage: randomImageView.image!.cgImage!, options: [:])
    do {
        let m = try VNCoreMLModel(for: model.model)
        let coreMLRequest = VNCoreMLRequest(model: m) { (request, error) in
            guard let observation = request.results?.first as? VNClassificationObservation else { return }
            let stop = DispatchTime.now()
            let nanoTime = stop.uptimeNanoseconds - start.uptimeNanoseconds
            let timeInterval = Double(nanoTime)
            self.classificationLabel.text = "\(observation.identifier) (\(observation.confidence * 100)%) in \(timeInterval) seconds."
        }
        try request.perform([coreMLRequest])
    } catch {
        print(error)
    }
}

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
    let mediaType = info[UIImagePickerControllerMediaType] as! NSString
    self.dismiss(animated: true, completion: nil)
    if mediaType.isEqual(to: kUTTypeImage as String) {
        let image = info[UIImagePickerControllerOriginalImage]
            as! UIImage
        randomImageView.image = image
        if (newMedia == true) {
            UIImageWriteToSavedPhotosAlbum(image, self,
                                           #selector(ViewController.image(image:didFinishSavingWithError:contextInfo:)), nil)
        } else if mediaType.isEqual(to: kUTTypeMovie as String) {
            // Code to support video here
        }
    }
}

@objc func image(image: UIImage, didFinishSavingWithError error: NSErrorPointer, contextInfo:UnsafeRawPointer) {
    if error != nil {
        let alert = UIAlertController(title: "Save Failed",
                                      message: "Failed to save image",
                                      preferredStyle: UIAlertControllerStyle.alert)
        let cancelAction = UIAlertAction(title: "OK",
                                         style: .cancel, handler: nil)
        alert.addAction(cancelAction)
        self.present(alert, animated: true,
                     completion: nil)
    }
}

func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
    self.dismiss(animated: true, completion: nil)
}
}

Любая идея, почему я получаю вышеуказанную ошибку жирным шрифтом? Большое вам спасибо за ваше время.

Ответ 1

В iOS 11 добавлен NSPhotoLibraryAddUsageDescription.

Пожалуйста, добавьте в "info.plist" описание "Конфиденциальность - Добавление библиотек фотографий" в описание использования (строка), как и для других прав доступа.

Ссылка: https://developer.apple.com/library/content/documentation/General/Reference/InfoPlistKeyReference/Articles/CocoaKeys.html