Cordova iOS App:如何用PDFJS加载App沙盒中下载的PDF?
针对Cordova iOS离线PDF更新的解决方案
1. 关于写入www文件夹的可行性
不可行。Cordova打包后,www文件夹属于iOS应用签名包的一部分,是只读目录。任何尝试写入该目录的操作都会破坏应用签名,导致应用崩溃或被系统拒绝运行。所有下载的文件必须存储在沙盒的可写目录中,推荐使用Documents目录(不会被系统自动清理)或Library/Caches(可被系统清理,适合临时文件)。
2. 直接传入沙盒路径给PDFJS的方案
完全可行,这是比读取二进制流更高效的方案。PDFJS支持直接加载本地文件URL,只需注意路径格式正确:
实现步骤
- 确保已安装
cordova-plugin-file和cordova-plugin-file-transfer(用于文件下载和沙盒路径操作) - 获取沙盒可写目录的URL,下载PDF后直接将文件URL传入
PDFJS.getDocument()
示例代码
// 下载PDF到沙盒并通过PDFJS加载 function downloadAndRenderPDF() { const fileTransfer = new FileTransfer(); const remotePDFUrl = "https://your-server.com/latest-manual.pdf"; // 存储到Documents目录 const localFilePath = cordova.file.documentsDirectory + "manual_v2.pdf"; fileTransfer.download( remotePDFUrl, localFilePath, (fileEntry) => { // 将沙盒文件URL传入PDFJS PDFJS.getDocument(fileEntry.toURL()).promise.then((pdfDoc) => { // 复用原有PDFJS渲染逻辑(高亮、搜索等API完全兼容) console.log("PDF加载成功,总页数:", pdfDoc.numPages); // 示例:渲染第一页 pdfDoc.getPage(1).then((page) => { const canvas = document.getElementById("pdf-canvas"); const context = canvas.getContext("2d"); const viewport = page.getViewport({ scale: 1.5 }); canvas.height = viewport.height; canvas.width = viewport.width; page.render({ canvasContext: context, viewport: viewport }); }); }); }, (error) => { console.error("PDF下载失败:", error.code, error.source, error.target); } ); }
关键注意点
- 确保PDFJS的
workerSrc配置正确:worker脚本必须从www目录加载(沙盒无法访问),比如:PDFJS.workerSrc = "js/pdf.worker.js"; // 指向www下的worker文件 - 调整CSP策略:在
index.html的meta标签中允许本地文件加载,比如:<meta http-equiv="Content-Security-Policy" content="default-src 'self' file://* cdvfile://*; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' 'unsafe-eval';">
3. 其他优化的文件同步方案
- 版本化文件管理:给每个PDF和映射文件添加版本号(如文件名包含
v2、v3),下载前先对比服务器返回的版本与本地存储的版本(可存在localStorage或SQLite),仅下载更新的文件。 - 增量映射文件更新:如果映射文件体积较大,可只下载增量更新包(如JSON差异文件),与本地映射文件合并,减少流量消耗。
- 旧文件清理:每次下载新版本后,删除沙盒中旧版本的PDF和映射文件,避免占用过多存储空间。
- 离线缓存校验:将已下载文件的路径、版本、校验和存储在本地,启动时优先加载本地最新版本,无需每次请求服务器。
4. iOS权限配置
在config.xml中添加Documents目录的权限描述(适配iOS 10+):
<platform name="ios"> <config-file parent="NSDocumentsFolderUsageDescription" platform="ios" target="*-Info.plist"> <string>需要存储下载的手册文件以提供离线访问</string> </config-file> </platform>
内容的提问来源于stack exchange,提问作者hashcoder
相关产品推荐
相关产品推荐

