美文网首页
WKWebview 和 js 相互调用及传值

WKWebview 和 js 相互调用及传值

作者: 两个小棉袄 | 来源:发表于2020-06-23 15:34 被阅读0次

    webview 用的是WKWebView,需实现协议<WKScriptMessageHandler,WKNavigationDelegate,WKUIDelegate>

    // js调用oc
    // 原理
    //1、JS与iOS约定好JStoOC方法,用作JS在调用iOS时的方法;
    //2、iOS使用WKUserContentController的-addScriptMessageHandler:name:方法监听name为JStoOC的消息;
    //3、iOS在-userContentController:didReceiveScriptMessage:方法中读取name为JStoOC的消息数据message.body。

    关键代码如下

    // 初始化
    - (instancetype)init
    {
        self = [super init];
        if (self) {
            WKWebViewConfiguration *config = [WKWebViewConfiguration new];
            //初始化偏好设置属性:preferences
            config.preferences = [WKPreferences new];
            //是否支持JavaScript, 默认是yes ,也可以不设置
            config.preferences.javaScriptEnabled = YES;
            
            config.userContentController = [WKUserContentController new];
            // 注入方法名是 "JStoOC",可以在WKScriptMessageHandler代理中接收到js的调用
            [config.userContentController addScriptMessageHandler:self name:@"JStoOC"];
            
            // frame 可以根据实际情况设置
            _webView = [[WKWebView alloc]initWithFrame:CGRectMake(0, 0, 0,0) configuration:config];
            _webView.UIDelegate = self;
            _webView.navigationDelegate = self;
        }
        return self;
    }
    
    - (void)dealloc
    {
        // 注册了方法,一定要remove,防止循环引用
        [[self.webView configuration].userContentController removeScriptMessageHandlerForName:@"JStoOC"];
    }
    
    //WKScriptMessageHandler 协议的回调方法
    -(void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message{
         if ([message.name isEqualToString:@"JStoOC"]) {
            // js 传的参数在 message.body 里
            // 执行业务逻辑
            // ...
        }
    }
    

    // oc调用js
    // 原理
    //1、iOS与JS约定好OCtoJS方法,用作iOS在调用JS时的入口方法;
    //2、iOS在页面加载完成 或者 js主动调用oc注入方法需回传参数场景
    //3、iOS使用WKWebView的-evaluateJavaScript:completionHandler:方法执行拼接好的JS代码;
    //4、iOS通过completionHandler收到JS给OCtoJS方法的回调。

    // WKNavigationDelegate 协议的 回调方法,页面加载完,调用js 方法
    -(void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation{
       
         // 无参数场景
         [webView evaluateJavaScript:@"OCtoJS()" completionHandler:^(id data, NSError * _Nullable error) {
            // 调用js后, OC收到的回调方法
        }];
    }
    

    补充一点,这个是有参数的情况

    // 这个地方需要注意,
    -(void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation{
        
        // 方法名字及参数结构
    //    OCtoJS({
    //        "businessFunctionName" : "tokenData(业务方法名字)",
    //        "param" : {
    //            "key1" : "value1",
    //            "key2" : "value2",
    //        }
    //    })
    //
        NSDictionary *paramDic = @{@"businessFunctionName":@"tokenData",@"param":@{@"key1":@"value1",@"key2":@"value2"}};
        //转为json
        NSData *data = [NSJSONSerialization dataWithJSONObject:paramDic options:(NSJSONWritingPrettyPrinted) error:nil];
        NSString *paramStr = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
        NSString *jsonStr = [NSString stringWithFormat:@"OCtoJS(%@)",paramStr];
        [webView evaluateJavaScript:jsonStr completionHandler:^(id data, NSError * _Nullable error) {
            // 调用js后, OC收到的回调方法
        }];
    }
    
    

    相关文章

      网友评论

          本文标题:WKWebview 和 js 相互调用及传值

          本文链接:https://www.haomeiwen.com/subject/modhfktx.html