如何从 UIImagePickerController 获取授权的 PHAsset?

How to get an authorized PHAsset from UIImagePickerController?

我有这个代码:

@IBAction func importButtonPressed(_ sender: Any) {
        self.imagePicker.sourceType = .photoLibrary
        self.imagePicker.allowsEditing = true
        self.imagePicker.mediaTypes = [kUTTypeMovie as String, kUTTypeImage as String]

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

这完美地呈现了 UIImagePicker。然后当我想使用选择的项目来获取 PHAsset 的日期时:

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
        guard info[UIImagePickerControllerMediaType] != nil else { return }
        let mediaType = info[UIImagePickerControllerMediaType] as! CFString
        switch mediaType {
        case kUTTypeImage:
            if let pickedImage = info[UIImagePickerControllerOriginalImage] as? UIImage {
                ...
            }
            break
        case kUTTypeMovie:
            if let videoURL = info[UIImagePickerControllerMediaURL] as? URL, let pickedAsset = info[UIImagePickerControllerPHAsset] as? PHAsset {
                print("kUTTypeMovie")
                MyVariables.isScreenshot = false
                let creationDate = pickedAsset.creationDate
                print(creationDate,"creationDate")
            }
            break
        case kUTTypeLivePhoto:
            print("livePhoto")
            dismiss(animated: true, completion: nil)

            break
        default:
            dismiss(animated: true, completion: nil)

            print("something else")
            break
        }
    }

现在,例如,当我选择一个视频时,print("kUTTypeMovie") 失败了,我想是因为 let pickedAsset = info[UIImagePickerControllerPHAsset] as? PHAsset 失败了

在其他地方 (UIImagePickerControllerDelegate get date from picked image in iOS 11) 我看到这可能是因为我需要授权才能选择 PHAssets。

所以我将我的第一个代码块更改为:

@IBAction func importButtonPressed(_ sender: Any) {

        let status = PHPhotoLibrary.authorizationStatus()

        switch status {
        case .authorized:
            PHPhotoLibrary.requestAuthorization({status in
                if status == .authorized {
                    self.imagePicker.sourceType = .photoLibrary
                    self.imagePicker.allowsEditing = true
                    self.imagePicker.mediaTypes = [kUTTypeMovie as String, kUTTypeImage as String]

                    self.present(self.imagePicker,animated: true, completion: nil)
                }
            })
        case .denied:
            print("denied")
        // probably alert the user that they need to grant photo access
        case .notDetermined:
            print("not determined")
        case .restricted:
            print("restricted")
            // probably alert the user that photo access is restricted
        }

    }

但是现在当我按下导入按钮时它崩溃并出现 lldb 错误:

libsystem_kernel.dylib`__abort_with_payload:
    0x1854f7040 <+0>:  mov    x16, #0x209
    0x1854f7044 <+4>:  svc    #0x80
->  0x1854f7048 <+8>:  b.lo   0x1854f7060               ; <+32>
    0x1854f704c <+12>: stp    x29, x30, [sp, #-0x10]!
    0x1854f7050 <+16>: mov    x29, sp
    0x1854f7054 <+20>: bl     0x1854d8bdc               ; cerror_nocancel
    0x1854f7058 <+24>: mov    sp, x29
    0x1854f705c <+28>: ldp    x29, x30, [sp], #0x10
    0x1854f7060 <+32>: ret    

很明显我做的不对。我该怎么做?

崩溃是因为缺少访问照片库的权限,

This app has crashed because it attempted to access privacy-sensitive data without a usage description. The app's Info.plist must contain an NSPhotoLibraryUsageDescription key with a string value explaining to the user how the app uses this data.

在您的 Info.plist 中,添加 NSPhotoLibraryUsageDescription 键和下面的一些描述,它将正常工作

Edit 您还应该按照以下正确方式使用 PhotoLibrary 授权。

@IBAction func importButtonPressed(_ sender: Any) {

    PHPhotoLibrary.requestAuthorization({status in
        switch status {
        case .authorized:
            self.imagePicker.sourceType = .photoLibrary
            self.imagePicker.allowsEditing = true
            self.imagePicker.mediaTypes = [kUTTypeMovie as String, kUTTypeImage as String]

            self.present(self.imagePicker,animated: true, completion: nil)
        case .denied:
            print("denied")
        // probably alert the user that they need to grant photo access
        case .notDetermined:
            print("not determined")
        case .restricted:
            print("restricted")
            // probably alert the user that photo access is restricted
        }
    })
}