西部数码如何建设自己的网站,培训机构加盟店排行榜,wordpress 自定义鼠标,wordpress部署到tomcatWKWebview 下载文件需要通过JS注入的方式来下载。js下载的数据是base64编码的#xff0c;回到给原生后#xff0c;原生需要反编码后才是原始文件的数据。 具体步骤#xff1a;
配置WKWebview的js回调句柄#xff08;标识#xff09;创建WKWebview并添加到视图上实现WKScr…WKWebview 下载文件需要通过JS注入的方式来下载。js下载的数据是base64编码的回到给原生后原生需要反编码后才是原始文件的数据。 具体步骤
配置WKWebview的js回调句柄标识创建WKWebview并添加到视图上实现WKScriptMessageHandler的(void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message处理下载的数据实现WKNavigationDelegate的 (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler注入js下载代码
配置WKWebview的js回调句柄标识并创建
WKWebViewConfiguration *config [[WKWebViewConfiguration alloc] init];
WKPreferences *preference config.preferences;
preference.javaScriptEnabled YES;
WKUserContentController * wkUController [[WKUserContentController alloc] init];
[wkUController addScriptMessageHandler:self name:onBlobData];
config.userContentController wkUController;
self.webView [[WKWebview alloc] initWithFrame:self.bounds configuration:config];关键代码 [wkUController addScriptMessageHandler:self name:“onBlobData”]; onBlobData 就是我们定义给js调回来的接口或标识
#实现WKScriptMessageHandler 代理 重点实现函数didReceiveScriptMessage这里需要捕获我们上一步定义的标识事件“onBlobData”并处理对应的数据
-(void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message{if ([message.name isEqualToString:onBlobData]) {NSString * content message.body;content [content stringByReplacingOccurrencesOfString:data:text/xml;base64, withString:];// 踢出头部信息[self saveFile:content];}
}content 的值如下
data:text/xml;base64,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其中前面的’data:text/xml;base64,表示文件的数据数据内容格式编码方式。对于不同的文件有不同的内容格式可根据具体已知要下载的文件类型存取或进一步判别这个头数据来处理。取数据时要去除这个头部信息之后再反编码直接存文件即可。
存文件
存文件的时候我们可以存到我们指定的位置一般情况下是弹框让用户来选定存放位置。
- (void)saveFile:(NSString *)content {NSDateFormatter *dateFormatter [[NSDateFormatter alloc]init];[dateFormatter setDateFormat:yyyyMMddHHmmss];NSString *dateString [dateFormatter stringFromDate:[NSDate date]];NSString *filename [NSString stringWithFormat:下载文件_%.txt,dateString];NSSavePanel *panel [NSSavePanel savePanel];[panel setAllowsOtherFileTypes:YES];[panel setAllowedFileTypes:[NSArray arrayWithObjects:txt, nil]];[panel setNameFieldStringValue:filename];[panel setExtensionHidden:YES];[panel setCanCreateDirectories:YES];[panel beginSheetModalForWindow:self.window completionHandler:^(NSInteger result){if (result NSFileHandlingPanelOKButton){NSString *filePath [[panel URL]path];dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{NSData *data [[NSData alloc] initWithBase64EncodedString:content options:0];//base64 反编码// Generate the file path[data writeToFile:filePath atomically:YES];//存到指定文件直接写入});}}];
}js下载代码注入
实现WKNavigationDelegate代理并在decidePolicyForNavigationAction 函数中捕获要下载的bloburl后进行下载
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler{NSLog(decidePolicyForNavigationAction :%,navigationAction.request);if (navigationAction.navigationType WKNavigationTypeLinkActivated) {NSString *loadUrl navigationAction.request.URL.absoluteString;if ([loadUrl containsString:blob:] [[loadUrl substringWithRange:NSMakeRange(0, 5)] isEqualToString:blob:]) {NSString *jsFormat [NSString stringWithFormat:var xhr new XMLHttpRequest();xhr.open(GET, %, true);xhr.responseType blob;xhr.onload function(e) {if (this.status 200) {var blob this.response;var reader new FileReader();reader.readAsDataURL(blob);reader.onloadend function() {window.webkit.messageHandlers.onBlobData.postMessage(reader.result); //通过onBlobData 调回给oc代码}}};xhr.send();,loadUrl];NSString * strJSCode [NSString stringWithFormat:%, jsFormat];[webView evaluateJavaScript:strJSCode completionHandler:^(id _Nullable data, NSError * _Nullable error) {NSLog(blob:%,strJSCode);}];}decisionHandler(WKNavigationActionPolicyCancel);NSLog(WKNavigationActionPolicyCancel);} else {decisionHandler(WKNavigationActionPolicyAllow);NSLog(WKNavigationActionPolicyAllow);}
}
重点说明xhr.open(‘GET’, ‘%’, true); 第二个参数需要替换为捕获到的blob url有些文章中介绍时使用‘(blob)’,就有人照抄代码调用了没有任何结果回调且还不知道是注入的代码不对还是请求不成功文中通过stringWithFormat将loadurl格式化到js代码中代码直接可用。有些文章中介绍时使用‘(blob)’,就有人照抄代码调用了没有任何结果回调且还不知道是注入的代码不对还是请求不成功文中通过stringWithFormat将loadurl格式化到js代码中代码直接可用。