Xcode13下iOS14.5~15.0版本WKWebView blob链接文件下载方案问询
问题核心原因
苹果在iOS14.5版本就已经实装了WKDownload系列API,但Xcode13内置的iOS15 SDK头文件错误地将该系列API的可用性标记从iOS14.5提升到了iOS15.0,才导致你遇到的构建失败问题,运行时iOS14.5~15.0的设备上该API是真实存在可调用的。
可行解决方案
方案1:手动修正WKDownloadDelegate的可用性声明(最推荐)
手动补充头文件声明,让Xcode13允许你在iOS14.5以上版本调用该系列API,运行时再做可用性校验即可:
// 仅在Xcode13+使用iOS15及以上SDK编译时生效 #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 150000 @protocol WKDownloadDelegate <NSObject> @required - (void)download:(WKDownload *)download decideDestinationUsingResponse:(NSURLResponse *)response suggestedFilename:(NSString *)suggestedFilename completionHandler:(void (^)(NSURL * _Nullable))completionHandler WK_API_AVAILABLE(ios(14.5)); @optional - (void)downloadDidFinish:(WKDownload *)download WK_API_AVAILABLE(ios(14.5)); - (void)download:(WKDownload *)download didFailWithError:(NSError *)error resumeData:(NSData * _Nullable)resumeData WK_API_AVAILABLE(ios(14.5)); @end #endif
- 调用前必须加运行时判断:
if (@available(iOS 14.5, *)) { 调用下载逻辑 } - 该方案无审核风险,是行业内通用的头文件可用性修正方案,完全兼容你之前已经写好的WKDownloadDelegate逻辑,不需要修改业务代码
方案2:Blob转Base64的JS注入适配方案
如果担心手动声明API的风险,可针对iOS14.5~15.0区间的设备用该方案过渡:
- 注入JS代码拦截页面上所有blob链接的点击事件,将blob文件读成Base64字符串后通过
WKScriptMessageHandler回传给原生
// 注入的JS代码 document.addEventListener('click', e => { const blobLink = e.target.closest('a[href^="blob:"]'); if (blobLink) { e.preventDefault(); fetch(blobLink.href).then(res => res.blob()).then(blob => { const reader = new FileReader(); reader.onloadend = () => { window.webkit.messageHandlers.blobHandler.postMessage({ base64Data: reader.result, fileName: blob.name || 'unknown' }); }; reader.readAsDataURL(blob); }); } }, true);
- 原生侧收到Base64数据后,去掉
data:xxx/xxx;base64,前缀,解码为NSData后写入沙盒即可
- 该方案缺点是大文件会占用较高内存,但是iOS14.5~15.0的用户占比极低,作为临时过渡方案完全可用
方案3:响应拦截方案
在WKNavigationDelegate的webView:decidePolicyForNavigationResponse:decisionHandler:方法中拦截下载请求的响应,直接读取响应体数据存储到沙盒,不需要走WKDownload相关逻辑。
内容的提问来源于stack exchange,提问作者NyrilX
相关产品推荐
相关产品推荐

