Swift开发文件类应用真机无法读取文件、提示无权限如何解决?
错误原因
iOS真机的沙盒权限限制远严于模拟器,你触发报错的核心原因是没有对外部来源的URL(比如从系统文件App选择、其他App跳转分享的文件URL)申请安全域访问权限,直接读取就会触发无权限报错。
可行解决方案
- 第一步:处理安全域权限申请
所有外部来源的文件URL,读取前必须调用startAccessingSecurityScopedResource()申请访问权限,访问完成后调用stopAccessingSecurityScopedResource()释放权限,这是苹果沙盒机制的强制要求。 - 第二步:补充Info.plist配置
如果你的App支持直接打开外部文件、或者需要开启iTunes文件共享,在项目的Info.plist中添加两个配置项:UIFileSharingEnabled设置为 YESLSSupportsOpeningDocumentsInPlace设置为 YES
- 第三步:修改你的文件读取逻辑,参考代码如下:
func presentDocument(at documentURL: URL) { let storyBoard = UIStoryboard(name: "Main", bundle: nil) let documentViewNavController = storyBoard.instantiateViewController(withIdentifier: "documentNavVc") // 先申请安全域访问权限 let hasAccess = documentURL.startAccessingSecurityScopedResource() defer { // 无论读取结果如何,最后都要释放权限 if hasAccess { documentURL.stopAccessingSecurityScopedResource() } } do { let text = try String(contentsOf: documentURL, encoding: .utf8) let name = documentURL.lastPathComponent if let documentViewController = documentViewNavController.contents as? DocumentViewController{ documentViewController.text = text documentViewController.title = name } } catch { print(error.localizedDescription) } documentViewNavController.modalPresentationStyle = .fullScreen present(documentViewNavController, animated: true, completion: nil) }
- 特殊场景适配:如果你是通过UIDocumentPickerViewController获取的文件URL,要确保你初始化选择器时的参数设置正确,如果你需要读取文件内容,初始化时传入的权限应该是
.open而不是.import,.import只会给你返回一个临时拷贝的URL,.open才能访问原文件。
内容的提问来源于stack exchange,提问作者razrabot
相关产品推荐
相关产品推荐

