我们都知道iOS WKWebView 跟JS通信的时候 由于JS Call OC 同步返回我这里采用了不同于异步messageHandler的通信方式,因此同步返回要单独进行设计
在我发现下面方法的时候 一般我们处理 与JS交互的时候都是 JS调用我们 然后我们再去调用JS方法 并不能同步给JS返回值
代理方法分析
在我们写WKWebView的时候需要遵守WKUIDelegate
协议 其中里面有这几个方法
// 获取js 里面的提示
-(void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler
{
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"提示" message:message preferredStyle:UIAlertControllerStyleAlert];
[alert addAction:[UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
completionHandler();
}]];
[self presentViewController:alert animated:YES completion:NULL];
}
// js 信息的交流
-(void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL))completionHandler
{
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"提示" message:message preferredStyle:UIAlertControllerStyleAlert];
[alert addAction:[UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
completionHandler(YES);
}]];
[alert addAction:[UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
completionHandler(NO);
}]];
[self presentViewController:alert animated:YES completion:NULL];
}
// 交互。可输入的文本。
-(void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString * _Nullable))completionHandler
{
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"textinput" message:@"JS调用输入框" preferredStyle:UIAlertControllerStyleAlert];
[alert addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) {
textField.textColor = [UIColor redColor];
}];
[alert addAction:[UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
completionHandler([[alert.textFields lastObject] text]);
}]];
[self presentViewController:alert animated:YES completion:NULL];
}
以上三个方法都是在js调用alert confirm prompt 的时候 进行拦截 然后弹出系统样式的界面
-
runJavaScriptConfirmPanelWithMessage
这个代理方法是在JS 调用alert('xxx')
的时候会调用 且回调函数参数为空 -
runJavaScriptConfirmPanelWithMessage
这个代理方法是在JS调用confirm函数的时候会进行拦截调用 且回调函数参数为Bool值 同步告诉JS 当前用户点击了确定按钮还是取消按钮 -
runJavaScriptTextInputPanelWithPrompt
这个代理方法是在JS调用prompt函数的时候进行拦截调用的 且回调函数的参数为NSString
类型
解决方法
细心的同学可能就已经明白了 在这个runJavaScriptTextInputPanelWithPrompt
代理方法中 可以回调字符串 也就意味着可以给JS返回值
可能有同学会问 我不需要那个弹出窗怎么办 其实你不需要的话 直接在代理方法中写
completionHandler("xxxx");
就行 不需要写UIAlertController
那一大堆
下面给出相应的具体代码
- JS部分 在需要跟原生交互的地方写下面的方法
window.prompt(text,defaultText);
text
可选。要在对话框中显示的提示信息(纯文本)
defaultText
可选。默认的输入文本。
一般只需要写text就行 defaultText 为空字符就可以
- OC部分 在js调用prompt方法后会来到相应的代理方法中
// 交互。可输入的文本。
-(void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString * _Nullable))completionHandler
{
NSLog(@"%@---%@",prompt,defaultText);
completionHandler(@"xxxxx");//这里就是要返回给JS的返回值
}
prompt
就是上面JS text
参数
defaultText
就是上面JS defaultText
参数
如果你需要做参数区分的话 可以灵活的运用这两个方法 去返回给JS不同的返回值
提示
如果要一次返回多个参数值 你可以把参数以逗号拼接为一个字符串 返回给JS 然后JS接收到参数的时候 再进行分割解析运用 这里只是给出一些想法 更多的就要靠同学们自己灵活运用了