2017-06-13 37 views
12

Vì vậy, đây là vấn đề của tôi. Tôi đang cố gắng tạo ra một màn hình trong đó có một UIImageView và một UIButton. Khi người dùng nhấn nút, ứng dụng máy ảnh mở ra, bạn chụp ảnh và nếu bạn nhấn "Sử dụng ảnh" trong ứng dụng Máy ảnh, bạn sẽ được đưa trở lại màn hình của ứng dụng và ảnh được đặt trong UIImageView mà tôi đã đề cập trước đó.Sự cố về quyền chụp ảnh trong iOS 11

gì xảy ra cho đến nay là khi tôi bấm nút "Sử dụng hình ảnh", hình ảnh được đặt một cách chính xác trong UIImageView của tôi nhưng sau đó treo ứng dụng với các lỗi sau:

Ứng dụng này đã bị rơi vì nó đã cố truy cập dữ liệu nhạy cảm về quyền riêng tư mà không cần mô tả sử dụng. Info.plist của ứng dụng phải chứa khóa NSPhotoLibraryAddUsageDescription có giá trị chuỗi giải thích cho người dùng cách ứng dụng sử dụng dữ liệu này.

Những gì tôi đã làm cho đến nay là:

  1. Đặt chìa khóa "Bảo mật - Thư viện ảnh Cách sử dụng Mô tả" với giá trị "$ (PRODUCT_NAME) sử dụng Thư viện để xử lý các bức ảnh bạn bị bắt. " trong tệp Info.plist (cũng đã kiểm tra cách nó được viết dưới dạng Nguồn và nó đúng theo Tài liệu dành cho nhà phát triển của Apple).

  2. Cũng đặt khóa "Quyền riêng tư - Mô tả sử dụng máy ảnh" có giá trị "$ (PRODUCT_NAME) sử dụng Máy ảnh" trong tệp Info.plist.

  3. Đã kiểm tra trong "TARGETS -> -> Thông tin-> Thuộc tính mục tiêu iOS tùy chỉnh" và 2 cặp khóa/giá trị mà tôi đã đề cập ở bước 1 và 2, tồn tại.

tôi sẽ cung cấp cho bạn mã của tôi cho đến nay:

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

Bất cứ ý tưởng tại sao tôi nhận được thông báo lỗi ở trên in đậm? Cảm ơn bạn rất nhiều trước cho thời gian của bạn.

Trả lời

35

NSPhotoLibraryAddUsageDescription đã được bổ sung trong iOS 11.

Vui lòng thêm "Bảo mật - Thư viện ảnh bổ sung Cách sử dụng Mô tả" trong info.plist với một mô tả việc sử dụng (string), như bạn đã làm cho các điều khoản riêng tư khác.

Tham khảo: https://developer.apple.com/library/content/documentation/General/Reference/InfoPlistKeyReference/Articles/CocoaKeys.html

+0

Cảm ơn bạn rất nhiều! Đây là câu trả lời. Bây giờ nó hoạt động hoàn hảo! –

+0

Tôi đã thêm điều này nhưng nó vẫn treo cho tôi. Tôi đang sử dụng phiên bản 9.0 beta 5. –

+0

@RubenZilibowitz Tôi đoán có lẽ bạn đã gõ sai phím plist. Ngoài ra, bạn có thể nhập "NSPhotoLibraryAddUsageDescription" và nó sẽ tự động thay đổi thành "Bảo mật - Mô tả sử dụng thư viện ảnh bổ sung". –

Các vấn đề liên quan