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

使用PHPickerViewController读取视频时报public.video类型加载错误如何解决

问题原因与解决方案

  • 第一步:检查PHPicker初始化的过滤配置
    绝大多数该报错是因为初始化选择器时没有正确指定视频类型过滤,导致返回结果内的itemProvider不包含视频类型的表示,另外必须导入UniformTypeIdentifiers框架,否则UTType会识别异常,正确初始化代码如下:
    import UniformTypeIdentifiers
    
    // 初始化PHPicker的代码
    var config = PHPickerConfiguration()
    config.filter = .videos // 仅选择视频用该配置,需要图文混选可替换为.any(of: [.images, .videos])
    config.selectionLimit = 1 // 单选设为1,多选按实际需求调整
    let picker = PHPickerViewController(configuration: config)
    picker.delegate = self
    present(picker, animated: true)
    
  • 第二步:优化代理方法逻辑,增加错误降级处理
    原代码缺少类型校验,且没有处理系统临时URL自动回收的问题,iOS 15.0~15.3版本还存在loadFileRepresentation随机报错的已知系统bug,调整后的兼容代码如下:
    func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
        dismiss(animated: true)
        guard let result = results.first, 
              let itemProvider = result.itemProvider,
              itemProvider.hasItemConformingToTypeIdentifier(UTType.video.identifier) else {
            print("无有效视频资源")
            return
        }
        
        // 优先使用官方推荐的加载方式
        itemProvider.loadFileRepresentation(forTypeIdentifier: UTType.video.identifier) { [weak self] url, error in
            if let error = error {
                print("loadFileRepresentation失败: \(error)")
                // 出错自动走备选加载方案
                self?.loadVideoByBackupMethod(itemProvider: itemProvider)
                return
            }
            guard let tempUrl = url else {
                self?.loadVideoByBackupMethod(itemProvider: itemProvider)
                return
            }
            // 系统返回的临时URL会在闭包结束后销毁,必须复制到自身沙盒目录留存
            let destUrl = FileManager.default.temporaryDirectory.appendingPathComponent(UUID().uuidString + ".mov")
            do {
                try FileManager.default.copyItem(at: tempUrl, to: destUrl)
                // 此处destUrl即为可用于上传Firebase Storage的稳定本地路径
                print("视频路径获取成功:\(destUrl)")
            } catch {
                print("临时文件复制失败: \(error)")
                self?.loadVideoByBackupMethod(itemProvider: itemProvider)
            }
        }
    }
    
    // 备选加载方案,适配系统bug场景
    private func loadVideoByBackupMethod(itemProvider: NSItemProvider) {
        itemProvider.loadItem(forTypeIdentifier: UTType.video.identifier, options: nil) { item, error in
            guard error == nil, let videoUrl = item as? URL else {
                print("视频加载失败,请重新选择")
                // 此处可弹出用户提示
                return
            }
            do {
                let videoData = try Data(contentsOf: videoUrl)
                let destUrl = FileManager.default.temporaryDirectory.appendingPathComponent(UUID().uuidString + ".mov")
                try videoData.write(to: destUrl)
                // 此处destUrl即为可用于上传Firebase Storage的稳定本地路径
                print("备选方案获取视频路径成功:\(destUrl)")
            } catch {
                print("视频读取失败: \(error)")
            }
        }
    }
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 02:24:03