iOS高级文章iOS 进阶

iOS WKWebView 同步返回值给JS

2018-08-03  本文已影响1264人  七里田间的守望者

我们都知道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 的时候 进行拦截 然后弹出系统样式的界面

解决方法

细心的同学可能就已经明白了 在这个runJavaScriptTextInputPanelWithPrompt 代理方法中 可以回调字符串 也就意味着可以给JS返回值
可能有同学会问 我不需要那个弹出窗怎么办 其实你不需要的话 直接在代理方法中写
completionHandler("xxxx");就行 不需要写UIAlertController那一大堆

下面给出相应的具体代码

window.prompt(text,defaultText);

text可选。要在对话框中显示的提示信息(纯文本)
defaultText可选。默认的输入文本。
一般只需要写text就行 defaultText 为空字符就可以

// 交互。可输入的文本。
-(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接收到参数的时候 再进行分割解析运用 这里只是给出一些想法 更多的就要靠同学们自己灵活运用了

完毕

上一篇下一篇

猜你喜欢

热点阅读