为什么通过UIDocumentPickerViewController选文件时url.bookmarkData返回nil
问题原因
- 核心原因是UIDocumentPickerViewController返回的云盘文件URL属于安全作用域URL,未调用权限申请接口直接访问时,系统会拦截访问请求,返回文件不存在的260错误。
- 未触发云盘文件的本地同步逻辑:OneDrive等第三方云盘的文件默认不会自动缓存到本地,直接访问URL路径时系统未触发下载流程,无法读取到文件实体。
.minimalBookmark配置兼容性问题:该配置仅生成包含最小信息的书签,对未在本地缓存的远程云文件兼容性极差,容易生成失败。
解决方案
- 先申请安全作用域访问权限
拿到选择的URL后必须先调用权限申请接口,访问完成后及时释放权限,示例代码如下:
// 申请安全作用域访问权限 let hasAccessPermission = url.startAccessingSecurityScopedResource() // 用完自动释放权限 defer { if hasAccessPermission { url.stopAccessingSecurityScopedResource() } }
- 使用NSFileCoordinator协调云文件访问
云文件的访问需要系统协调触发下载,不能直接读取URL路径,需要将文件操作包在文件协调器的回调中执行,同时替换书签生成的配置为兼容性更好的.suitableForBookmarkFile,示例代码如下:
let fileCoordinator = NSFileCoordinator() var coordinateError: NSError? fileCoordinator.coordinate(readingItemAt: url, options: .forUploading, error: &coordinateError) { coordinatedUrl in do { // 替换.minimalBookmark为.suitableForBookmarkFile提升云文件兼容性 let bookmark = try coordinatedUrl.bookmarkData(options: .suitableForBookmarkFile, includingResourceValuesForKeys: nil, relativeTo: nil) // 后续处理生成的书签 } catch { // 处理书签生成错误 } } if let error = coordinateError { // 处理文件协调错误 }
- 补充Info.plist配置
在项目的Info.plist中添加如下配置,提升云文件原地访问的兼容性:
UIFileSharingEnabled设置为YESLSSupportsOpeningDocumentsInPlace设置为YES
内容的提问来源于stack exchange,提问作者EsbenG
相关产品推荐
相关产品推荐

