You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHPickerView获取大视频URL失败:无法加载public.movie表示

问题:PHPickerView选择大视频时无法加载文件,提示文件不存在

尝试从PHPickerView的选择结果中获取相机胶卷内视频的URL时,仅在处理较大视频文件时出现错误,无法加载public.movie类型的表示,提示文件不存在。更换不同类型标识符也无法解决问题。

错误信息:
Error Domain=NSItemProviderErrorDomain Code=-1000 "Cannot load representation of type public.movie" UserInfo={NSLocalizedDescription=Cannot load representation of type public.movie, NSUnderlyingError=0x282932ca0 {Error Domain=NSCocoaErrorDomain Code=260 "The file couldn’t be opened because it doesn’t exist." UserInfo={NSFilePath=/private/var/mobile/Containers/Shared/AppGroup/E5CE1DB9-85C1-4378-94C2-D384E92C5268/File Provider Storage/photospicker/version=1&uuid=B42E6922-E10A-46DB-8B95-66B009F7294A&mode=compatible.mov, NSLocalizedDescription=The file couldn’t be opened because it doesn’t exist.}}}

相关代码片段:

result.itemProvider.loadFileRepresentation(forTypeIdentifier: UTType.movie.identifier)
{ videoURL, error in
                    
  assert(Thread.isMainThread == false)

  let directory = NSTemporaryDirectory()
  let fileName = NSUUID().uuidString.appending(".mov")

  if let videoURL = videoURL,
    let copiedURLFile = NSURL.fileURL(withPathComponents: [directory, fileName]) {
解决方案

1. 强引用持有PHPickerResult,避免临时文件被提前清理

大视频的加载是异步操作,如果PHPickerResult或NSItemProvider被提前释放,系统会自动清理生成的临时文件,导致文件不存在。可以在类中声明属性持有选中结果:

private var selectedResults: [PHPickerResult] = []

在选择完成后将结果存入该数组:

func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
    picker.dismiss(animated: true)
    selectedResults = results
    processResult(results.first!)
}

2. 使用loadInPlaceFileRepresentation替代loadFileRepresentation

loadFileRepresentation会创建文件副本,大文件复制耗时且易出问题;loadInPlaceFileRepresentation直接访问原始文件的临时链接,效率更高,也能避免副本丢失:

result.itemProvider.loadInPlaceFileRepresentation(forTypeIdentifier: UTType.movie.identifier) { [weak self] fileURL, isInPlace, error in
    guard let self = self else { return }
    if let error = error {
        print(error.localizedDescription)
        return
    }
    guard let fileURL = fileURL else { return }
    
    // isInPlace为true时,不能修改原文件,需复制到自定义目录再操作
    if isInPlace {
        let tempDir = FileManager.default.temporaryDirectory
        let targetURL = tempDir.appendingPathComponent("\(NSUUID().uuidString).mov")
        do {
            try FileManager.default.copyItem(at: fileURL, to: targetURL)
            // 后续使用targetURL处理视频
        } catch {
            print("复制文件失败:\(error)")
        }
    } else {
        // 非原地文件可直接操作fileURL
    }
}

3. 修正文件复制路径逻辑

避免手动拼接路径导致的错误,用FileManager提供的方法生成合法路径:

let tempDir = FileManager.default.temporaryDirectory
let targetURL = tempDir.appendingPathComponent("\(NSUUID().uuidString).mov")
do {
    try FileManager.default.copyItem(at: videoURL, to: targetURL)
    // 使用targetURL进行后续处理
} catch {
    print("复制文件失败:\(error)")
}

4. 注意线程切换

异步回调默认在后台线程,如果后续需要更新UI,必须切回主线程,避免UI操作异常。

内容的提问来源于stack exchange,提问作者EAO123

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 17:05:19