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

iOS17设备中PHPickerViewController获取视频缩略图权限问题求助

iOS17真机获取视频缩略图报“无权限查看”问题解决

问题原因

iOS17开始,通过UIDocumentPickerViewController或PHAsset的itemProvider获取的媒体文件URL是安全范围URL(Security-Scoped URL),这类URL包含权限校验参数(即你打印路径里的&type=3&mode=2等)。直接用AVURLAsset访问时,因未主动申请并保留访问权限,会触发“无权限查看”错误。模拟器沙箱限制较宽松,所以不会出现该问题。

解决方案

1. 保留安全范围URL的访问权限

对获取到的URL,必须调用startAccessingSecurityScopedResource()申请访问权限,操作完成后调用stopAccessingSecurityScopedResource()释放权限,这一对方法必须配对使用。

2. 避免将URL转为字符串处理

你当前代码把NSURL转成absoluteString再处理的方式错误,会丢失安全范围URL的权限信息,应直接使用URL类型对象。

修改后的代码示例

获取视频的代码调整:

guard results.count > 0 else { return } 
for asset in results {
    if asset.itemProvider.hasItemConformingToTypeIdentifier(UTType.movie.identifier) {
        asset.itemProvider.loadItem(forTypeIdentifier: UTType.movie.identifier) { [weak self] movie, error in
            guard let self = self, error == nil else { return }
            // 直接转为URL,不要转成字符串
            guard let url = movie as? URL else { return }
            
            // 检查是否是安全范围URL并申请权限
            guard url.startAccessingSecurityScopedResource() else {
                print("无法获取文件访问权限")
                return
            }
            defer {
                // 操作完成后释放权限
                url.stopAccessingSecurityScopedResource()
            }
            
            // 调用缩略图生成方法
            do {
                if let thumbnail = try url.thumbnailForMovie() {
                    // 处理生成的缩略图
                }
            } catch {
                print("生成缩略图失败:\(error)")
            }
        }
    }
}

获取缩略图的代码调整:

extension URL {
    func thumbnailForMovie() throws -> UIImage? {
        let asset = AVURLAsset(url: self, options: [AVURLAssetPreferPreciseDurationAndTimingKey: true])
        let generator = AVAssetImageGenerator(asset: asset)
        generator.appliesPreferredTrackTransform = true
        
        // 用CMTimeZero取第一帧更稳妥,避免使用无效的asset.duration
        let timestamp = CMTime.zero
        do {
            let cgImage = try generator.copyCGImage(at: timestamp, actualTime: nil)
            return UIImage(cgImage: cgImage)
        } catch {
            throw error
        }
    }
}

额外注意事项

  • 确保App已开启App Sandbox权限(在Xcode的Signing & Capabilities中开启),并勾选User Selected File的读写权限(若从文件选择器获取资源)。
  • 若从相册获取PHAsset,也可直接用PHImageManager获取缩略图,绕开安全范围URL的权限处理:
let imageManager = PHImageManager.default()
let requestOptions = PHImageRequestOptions()
requestOptions.isSynchronous = true
requestOptions.deliveryMode = .highQualityFormat
imageManager.requestImage(for: asset, targetSize: CGSize(width: 200, height: 200), contentMode: .aspectFill, options: requestOptions) { image, _ in
    // 处理拿到的缩略图image
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 07:27:16