如何从 UIImagePickerController 获取授权的 PHAsset?

Posted

技术标签:

【中文标题】如何从 UIImagePickerController 获取授权的 PHAsset?【英文标题】:How to get an authorized PHAsset from UIImagePickerController? 【发布时间】:2018-06-03 19:19:07 【问题描述】:

我有这个代码:

@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) 我看到这可能是因为我需要授权才能选择 PHAsset。

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

@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    

很明显,我没有正确地做到这一点。我该怎么做?

【问题讨论】:

【参考方案1】:

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

此应用已崩溃,因为它试图在没有使用说明的情况下访问隐私敏感数据。应用的 Info.plist 必须包含一个 NSPhotoLibraryUsageDescription 键和一个字符串值,向用户解释应用如何使用这些数据。

在您的Info.plist 中,添加NSPhotoLibraryUsageDescription 键,并附上如下说明,这样就可以正常工作了

编辑 您还应该按照以下正确方式使用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
        
    )

【讨论】:

以上是关于如何从 UIImagePickerController 获取授权的 PHAsset?的主要内容,如果未能解决你的问题,请参考以下文章

如何调整自定义 UIButton 的图像大小?

iPhone - 以编程方式删除状态栏

imageWithData图像尺寸变大了?

Segue 图像到另一个视图控制器的问题

imagePickerController 选择照片时出错

如何从其他面板从 JTextField 获取输入