为什么从 PHAsset 转换时 url 有时会出现 nil? (Swift)

Why does the url sometimes come out nil when converting from PHAsset? (Swift)

不得不重新post 这个问题,因为没有人回答,已经 2 周了,我完全不知道为什么会这样。 我正在使用以下函数将 PHAsset 转换为 url:

extension PHAsset {

    func getURL(completionHandler : @escaping ((_ responseURL : URL?) -> Void)){
        if self.mediaType == .image {
            let options: PHContentEditingInputRequestOptions = PHContentEditingInputRequestOptions()
            options.canHandleAdjustmentData = {(adjustmeta: PHAdjustmentData) -> Bool in
                return true
            }
            options.isNetworkAccessAllowed = true
            self.requestContentEditingInput(with: options, completionHandler: {(contentEditingInput: PHContentEditingInput?, info: [AnyHashable : Any]) -> Void in
                completionHandler(contentEditingInput!.fullSizeImageURL as URL?)
            })
        } else if self.mediaType == .video {
            let options: PHVideoRequestOptions = PHVideoRequestOptions()
            options.version = .original
            options.isNetworkAccessAllowed = true
            PHImageManager.default().requestAVAsset(forVideo: self, options: options, resultHandler: {(asset: AVAsset?, audioMix: AVAudioMix?, info: [AnyHashable : Any]?) -> Void in
                if let urlAsset = asset as? AVURLAsset {
                    let localVideoUrl: URL = urlAsset.url as URL
                    completionHandler(localVideoUrl)
                } else {
                    completionHandler(nil)
                }
            })
        }
    }
}

但是 url 最终会出现 nil 有时会导致我的应用程序崩溃。我注意到如果我选择长边的视频而不是图片,这种情况更常见,但我无法准确指出它发生的时间。此外,这似乎不是我遇到的问题,因为在堆栈溢出 post 我从中得到了这个,最近的评论询问为什么资产有时为零。 post: How to get URL for PHAsset? [复制]

编辑

我将代码更改为:

func getURL(completionHandler : @escaping ((_ responseURL : URL?) -> Void)){
        if self.mediaType == .image {
            let options: PHContentEditingInputRequestOptions = PHContentEditingInputRequestOptions()
          //  options.canHandleAdjustmentData = {(adjustmeta: PHAdjustmentData) -> Bool in
          //      return true
         //   }
           // options.isNetworkAccessAllowed = true
            self.requestContentEditingInput(with: options, completionHandler: {(contentEditingInput: PHContentEditingInput?, info: [AnyHashable : Any]) -> Void in
                if let contentEditingInput = contentEditingInput {
                   completionHandler(contentEditingInput.fullSizeImageURL)
                } else {
                   completionHandler(nil)
                }
            })
        } else if self.mediaType == .video {
            let options: PHVideoRequestOptions = PHVideoRequestOptions()
         //   options.version = .original
        //    options.isNetworkAccessAllowed = true
            PHImageManager.default().requestAVAsset(forVideo: self, options: options, resultHandler: {(asset: AVAsset?, audioMix: AVAudioMix?, info: [AnyHashable : Any]?) -> Void in
                if let urlAsset = asset as? AVURLAsset {
                    let localVideoUrl: URL = urlAsset.url as URL
                    completionHandler(localVideoUrl)
                } else {
                    completionHandler(nil)
                }
            })
        }
    }

但还是没有运气。我的应用程序并没有崩溃,只是时不时地出现 urls 结果为零。

self.requestContentEditingInput(with: options, completionHandler: {(contentEditingInput: PHContentEditingInput?, info: [AnyHashable : Any]) -> Void in
                completionHandler(contentEditingInput!.fullSizeImageURL as URL?)
            })

contentEditingInput 被标记为可选,为什么有人会隐式解包它超出了我的范围。要安全地解包它(这将防止您的应用程序崩溃),请执行以下操作:

if let contentEditingInput = contentEditingInput {
   completionHandler(contentEditingInput.fullSizeImageURL)
} else {
   completionHandler(nil)
}

您不需要 as URL? 因为,文档:

var fullSizeImageURL: URL? { get }

尝试注释掉设置图像 options 的行。 我有一个使用此 API 的应用程序工作正常,但我没有设置这些选项.此选项可能是 contentEditingInput 为 nil 的原因。

编辑 - 使用 UIImagePickerController

从照片库中获取 URL 图像或电影
import MobileCoreServices

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
        guard let mediaType = info[UIImagePickerController.InfoKey.mediaType] as? String,
              mediaType == (kUTTypeMovie as String) else { return }
        let videoURL = info[.mediaURL] as? URL
    }

上面是我以前获取视频的方式URL,下面是获取图片的方式

guard let mediaType = info[UIImagePickerController.InfoKey.mediaType] as? String,
                  mediaType == (kUTTypeImage as String) else { return }
let photoURL = info[.imageURL] as? URL