在与js
的交互中需要给js
提供一个方法来判断是否安装了某一个应用,但是系统提供的方法并没有返回参数,难道返回参数的时候还要先js
调用原生方法,原生方法处理完成后再调用js
的方法?瞬间感觉WKWebView
就成了残疾。
解决方法
如果逻辑上不影响,而且js
不需要传参数给原生的时候。
可以事先设置一个变量到js
中,当js
调用原生方法的时候,直接把最后的结果设置到事先设定的变量上面,js
直接调用事先设定好的变量获取结果。
参考这篇文章
如果js
那边需要传值过来的时候就无法满足了。找来找去就只有输入框的回调可以返回一个字符串回去,就是WKUIDelegate
的这个方法,其中prompt
可以作为方法名传过来,defaultText
可以作为参数传过来。
- (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString * _Nullable))completionHandler{
completionHandler(@"你的返回值");
}
正常的WKWebView设置
WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc] init];
self.webView = [[WKWebView alloc] initWithFrame:self.view.bounds configuration:config];
self.webView.navigationDelegate = self;
//这里设置弹框、输入框等回调
self.webView.UIDelegate = self;
//设置js回调的方法
[[self.webView configuration].userContentController addScriptMessageHandler:self name:@"isInstall"];
[self.view addSubview:self.webView];
NSURL * url=[NSURL URLWithString:@"http://10.2.205.102:8080/#/"];
NSURLRequest * request=[[NSURLRequest alloc] initWithURL:url];
[self.webView loadRequest:request];
加载过程回调
#pragma mark WKNavigationDelegate
// 页面加载完成之后调用
- (void)webView:(WKWebView *)webView didFinishNavigation:(null_unspecified WKNavigation *)navigation{
}
// 当main frame开始加载数据失败时,会回调
- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(null_unspecified WKNavigation *)navigation withError:(NSError *)error {
}
// 当main frame最后下载数据失败时,会回调
- (void)webView:(WKWebView *)webView didFailNavigation:(null_unspecified WKNavigation *)navigation withError:(NSError *)error {
}
弹框、编辑框等UI回调
#pragma mark WKUIDelegate
- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler{
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"提示" message:message?:@"" preferredStyle:UIAlertControllerStyleAlert];
[alertController addAction:([UIAlertAction actionWithTitle:@"确认" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
completionHandler();
}])];
[self presentViewController:alertController animated:YES completion:nil];
}
- (void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL))completionHandler{
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"提示" message:message?:@"" preferredStyle:UIAlertControllerStyleAlert];
[alertController addAction:([UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
completionHandler(NO);
}])];
[alertController addAction:([UIAlertAction actionWithTitle:@"确认" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
completionHandler(YES);
}])];
[self presentViewController:alertController animated:YES completion:nil];
}
- (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString * _Nullable))completionHandler{
//根据prompt进行判断执行相应的方法,defaultText为参数值,completionHandler为给js的回调
[self.appHelp doFunction:prompt value:defaultText completionHandler:completionHandler];
//注意这里一定要调用completionHandler(@"");不然会crash
}
js
的回调
#pragma mark WKScriptMessageHandler
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message {
//message.name 方法名
//message.body 参数值
}
正常js
调用,这里需要try catch
一下不然会报错
try{
window.webkit.messageHandlers.isInstall.postMessage(identify);
}catch (e){
}
利用弹框的方式调用方法
var isInstall =prompt('isInstallApp',appId);
网友评论