UIDocumentBrowser模拟器正常iPad无法打开PDF问题求助 [iOS Swift]
问题根因
这个问题是iOS沙盒安全机制限制导致的,模拟器对文件访问的限制较松所以正常运行,真机环境下必须遵守安全作用域URL的访问规则:
通过UIDocumentBrowserViewController获取到的外部文件URL均属于安全作用域URL,必须先主动申请访问权限,才能读取URL对应的文件内容,你当前跳过了权限申请步骤,所以真机上PDFDocument初始化失败返回nil。
修复步骤
1. 申请文件访问权限
修改presentDocument方法,在初始化PDFDocument前先申请访问权限:
func presentDocument(at documentURL: URL) { // 原有代码不变,先申请安全作用域访问权限 guard documentURL.startAccessingSecurityScopedResource() else { os_log("无法获取文件访问权限", log: .default, type: .error) // 此处可补充权限申请失败的用户提示逻辑 return } let storyBoard = UIStoryboard(name: "Main", bundle: nil) // 原有加载视图控制器、转场控制器的代码不变 transitionController = transitionController(forDocumentAt: documentURL) // 现在可以正常读取PDF文件了 guard let doc = PDFDocument(url: documentURL) else { os_log("PDF文件初始化失败", log: .default, type: .error) documentURL.stopAccessingSecurityScopedResource() return } transitionController!.targetView = documentViewController.pdfView // 把URL也传递给文档视图控制器,方便后续释放权限 documentViewController.document = doc documentViewController.documentURL = documentURL // 需要先在TextDocumentViewController中新增这个属性 // 原有弹出控制器的代码不变 docNavController.modalPresentationStyle = .fullScreen self.present(docNavController, animated: true, completion: nil) }
2. 新增属性存储文件URL
在TextDocumentViewController中新增属性存储文件URL,用于后续释放权限:
class TextDocumentViewController: UIViewController, PDFDocumentDelegate, PDFViewDelegate { // 原有属性不变,新增以下属性 var documentURL: URL! // 原有代码不变 }
3. 释放访问权限
在文档关闭时释放安全作用域访问权限,避免资源泄漏:
override func viewDidDisappear(_ animated: Bool) { super.viewDidDisappear(animated) documentURL.stopAccessingSecurityScopedResource() }
其他可选排查点
如果修复后仍存在问题,可以按以下顺序排查:
- 检查项目
Info.plist中是否正确配置了PDF文件的文档类型,对应的UTI应为com.adobe.pdf - 打印
FileManager.default.isReadableFile(atPath: documentURL.path)确认文件路径合法且可读 - 确认测试用的PDF文件本身没有损坏,可尝试用系统Files应用打开验证
内容的提问来源于stack exchange,提问作者user8460166
相关产品推荐
相关产品推荐

