iOS 11.3生成PDF遇写入权限错误,iOS 11.2运行正常
嘿,这个问题我之前帮同事排查过,刚好是iOS 11.3沙盒权限收紧导致的,来给你拆解下:
问题根源
你看到的报错CGDataConsumerCreateWithFilename: failed to open '/note.pdf' for writing: Operation not permitted是关键——这里代码尝试写入根目录的/note.pdf,但iOS 11.3开始对沙盒外的路径(比如根目录)做了更严格的权限限制,完全禁止App写入;而iOS 11.2的权限管控没这么严,所以之前能正常运行。
你说“PDF可正常生成,但上传时触发错误”,大概率是PDF生成逻辑是在临时路径(比如内存或系统临时目录)完成的,但上传环节错误地指向了根目录的/note.pdf,才触发了权限报错。
解决方案
核心就是确保所有文件操作都使用沙盒内的文档目录URL,别碰根路径:
修正PDF生成/访问的全流程路径
你已经正确获取了文档目录的URL,但要确保PDF生成和上传的每一步都用这个路径,而不是硬编码/note.pdf。比如用Core Graphics生成PDF时,要传入沙盒URL的CFURL版本:let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0] let fileURL = documentsURL.appendingPathComponent("note.pdf") // 生成PDF时用这个正确的URL guard let pdfContext = CGPDFContextCreateWithURL(fileURL as CFURL, nil, nil) else { // 处理创建失败 return } // 执行PDF绘制逻辑... CGPDFContextClose(pdfContext) // 上传时直接用这个fileURL uploadFile(at: fileURL)验证路径正确性
可以在代码里打印fileURL.path确认,正确的路径应该是沙盒内的格式,比如:/var/mobile/Containers/Data/Application/[一串随机UUID]/Documents/note.pdf如果打印出来是
/note.pdf,那肯定是某个环节硬编码了根路径,得彻底排查代码里的路径字符串。清理旧文件的注意事项
如果有删除旧PDF的逻辑,也要用FileManager操作同一个fileURL,避免路径不一致:do { try FileManager.default.removeItem(at: fileURL) } catch { // 文件不存在的话忽略错误即可 }
总结
本质就是iOS 11.3的沙盒权限升级,把之前“睁一只眼闭一只眼”的根目录写入操作彻底禁止了,只要把所有文件操作都限定在App自己的沙盒文档目录里,问题就能解决。
内容的提问来源于stack exchange,提问作者Preetika

