作者:860520430_a87a12 | 来源:互联网 | 2023-02-01 13:04
所以这是我的问题.我正在尝试创建一个屏幕,其中有一个UIImageView和一个UIButton.当用户按下按钮时,相机应用程序打开,您拍摄照片,如果您在相机应用程序中按"使用照片",您将返回到我的应用程序屏幕,照片将放在我之前提到的UIImageView中.
到目前为止发生的事情是,当我按下"使用照片"按钮时,图像被正确放置在我的UIImageView中,但随后应用程序崩溃并出现以下错误:
此应用程序已崩溃,因为它试图在没有使用说明的情况下访问隐私敏感数据.应用程序的Info.plist必须包含一个NSPhotoLibraryAddUsageDescription键,其中包含一个字符串值,向用户解释应用程序如何使用此数据.
到目前为止我所做的是:
放置密钥"隐私 - 照片库使用说明",其值为"$(PRODUCT_NAME)使用库以处理您捕获的照片".在Info.plist文件中(还检查了它是如何以源代码形式编写的,并且根据Apple开发人员文档它是正确的).
还在Info.plist文件中放置了"隐私 - 相机使用说明"键,其值为"$(PRODUCT_NAME)使用相机".
检查"目标 - > - >信息 - >自定义iOS目标属性"和我在步骤1和2中提到的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> Kurt J..:
iOS 11中添加了NSPhotoLibraryAddUsageDescription.
请在info.plist中添加"隐私 - 照片库添加使用说明",其中包含使用说明(字符串),就像您对其他隐私权限所做的那样.
参考:https://developer.apple.com/library/content/documentation/General/Reference/InfoPlistKeyReference/Articles/CocoaKeys.html