如何在WKWebView中本地保存网站并实现离线加载?
实现WKWebView离线加载网站的可行方案
一、替代已失效的OfflineWebApplicationCache方案
原WKWebsiteDataTypeOfflineWebApplicationCache已被废弃,目前可通过以下两种方式实现离线加载:
1. 利用HTTP缓存策略
创建请求时设置缓存优先级,让WKWebView优先读取本地缓存,无缓存再请求网络:
let targetURL = URL(string: "https://your-target-site.com")! let request = URLRequest(url: targetURL, cachePolicy: .returnCacheDataElseLoad, timeoutInterval: 30) webView.load(request)
配合服务器端设置的Cache-Control、Expires等HTTP响应头,WebView会自动缓存符合规则的资源,实现基础离线访问。
2. 借助WKWebsiteDataStore管理缓存
通过WKWebsiteDataStore可以查看或管理WebView的缓存数据:
let dataStore = WKWebsiteDataStore.default() dataStore.fetchDataRecords(ofTypes: WKWebsiteDataStore.allWebsiteDataTypes()) { records in // 遍历records可查看所有缓存记录,如需清理可调用removeData方法 dataStore.removeData(ofTypes: WKWebsiteDataStore.allWebsiteDataTypes(), for: records) { // 缓存清理完成 } }
二、手动下载网站资源并本地存储
如果需要完全控制离线资源,可手动下载网页及静态资源,步骤如下:
1. 下载并保存网页HTML
使用URLSession请求网页内容,保存到本地沙盒:
let session = URLSession.shared session.dataTask(with: targetURL) { data, response, error in guard let data = data, let htmlContent = String(data: data, encoding: .utf8) else { return } // 保存到Documents目录 let docsDir = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first! let localHTMLPath = docsDir.appendingPathComponent("offline_page.html") try? htmlContent.write(to: localHTMLPath, atomically: true, encoding: .utf8) }.resume()
2. 下载并替换静态资源
解析HTML中的CSS、JS、图片等资源链接,批量下载后替换为本地路径:
- 可使用SwiftSoup等HTML解析库提取所有资源URL
- 逐个下载资源到本地指定目录(如
Documents/assets/) - 将HTML中的远程资源路径替换为本地文件路径(例如
file:///xxx/Documents/assets/style.css)
3. 加载本地离线网页
离线时直接加载本地保存的HTML文件:
let docsDir = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first! let localHTMLPath = docsDir.appendingPathComponent("offline_page.html") webView.loadFileURL(localHTMLPath, allowingReadAccessTo: docsDir)
三、补充参考方案
若目标网站已配置Service Worker,iOS 11及以上版本的WKWebView会自动支持离线访问,无需额外代码,只需确保WebView允许JavaScript执行(默认开启)。Service Worker会在后台自动缓存网站资源,实现更完善的离线体验。
内容的提问来源于stack exchange,提问作者Deep Gandhi
相关产品推荐
相关产品推荐

