美文网首页
1.WebView与OC通讯方式

1.WebView与OC通讯方式

作者: 你weixiao的时候很美 | 来源:发表于2019-01-18 13:33 被阅读25次

    参考:
    WK 与 JS 的那些事 WKWebView使用
    H5 与 Native 交互之 JSBridge 技术

    1.简介

    从iOS12开始,苹果正式废弃UIWebView,使用WKWebView。使用WebView的主要问题是原生OC如何与webView通讯的问题,即 js与oc的如何交互。

    UIWebView与WKWebView比较:
    1.内存占用,加载速度wkwebview有优势.
    2.wkwebview将协议和类拆分,更清晰.
    3.wkwebview带有进度属性estimatedProgress.
    4.wkwebview不支持页面缓存,需要自己注入cookie,而uiwebview是自动注入cookie.
    5.wkwebview无法使用jscontext.

    2. 原理

    1.使用原生调用js
    其实就是调用了window下的一个对象,如果我们要让native来调用我们js写的方法,那这个方法就要在window下能访问到.

    2.使用js调用原生oc
    在webView内发起网络请求都可以被原生拦截.

    我们发起一个自定义的网络请求,通常格式: jsbridge://methodName?param1=value1&param2=value2. 发现是jsbridge://开头的地址,就不进行内容的加载,转而执行相应的调用逻辑

    发起这样一个网络请求有两种方式:1. 通过localtion.href;2. 通过iframe方式. 我们通过设置一个隐藏的ifrmame来达到发送自定义请求的目的.

    3.交互方式:
    使用WKWebview时,原生oc与js交互的主要思想是拦截。有一下几种方式:

    1. 直接拦截js的url跳转。
    2. 使用messageHandle。
    3. 使用三方如WebViewJavaScriptBridge
    3.直接拦截js的响应方法。

    1.js告诉oc要跳转
    WKWebView实现WKNavigationDelegate,当js跳转的时候,代理会实现

    - (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler{
        //根据navigationAction.request 可以拦截每一个js执行的超链接。
        decisionHandler(WKNavigationActionPolicyAllow);
    }
    

    顺便说一下,WKNavigationDelegate是webView页面跳转时候的代理:

    #pragma mark - WKNavigationDelegate
    //请求之前,决定是否要跳转:用户点击网页上的链接,需要打开新页面时,将先调用这个方法。
    - (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler;
    //接收到相应数据后,决定是否跳转
    - (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler;
    //页面开始加载时调用
    - (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(null_unspecified WKNavigation *)navigation;
    // 主机地址被重定向时调用
    - (void)webView:(WKWebView *)webView didReceiveServerRedirectForProvisionalNavigation:(null_unspecified WKNavigation *)navigation;
    // 页面加载失败时调用
    - (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(null_unspecified WKNavigation *)navigation withError:(NSError *)error;
    // 当内容开始返回时调用
    - (void)webView:(WKWebView *)webView didCommitNavigation:(null_unspecified WKNavigation *)navigation;
    // 页面加载完毕时调用
    - (void)webView:(WKWebView *)webView didFinishNavigation:(null_unspecified WKNavigation *)navigation;
    //跳转失败时调用
    - (void)webView:(WKWebView *)webView didFailNavigation:(null_unspecified WKNavigation *)navigation withError:(NSError *)error;
    // 如果需要证书验证,与使用AFN进行HTTPS证书验证是一样的
    - (void)webView:(WKWebView *)webView didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential *__nullable credential))completionHandler;
    //9.0才能使用,web内容处理中断时会触发
    - (void)webViewWebContentProcessDidTerminate:(WKWebView *)webView NS_AVAILABLE(10_11, 9_0);
    

    2.OC告诉js执行方法

    - (void)evaluateJavaScript:(NSString *)javaScriptString completionHandler:(void (^ _Nullable)(_Nullable id, NSError * _Nullable error))completionHandler
    
    //webview 调用该方法使js执行 javaScriptString的代码。
    
    4. 使用messageHandler

    1.js调用oc(js给oc发消息)

    1.实现方式
    WKWebview原生通过实现userContentController类添加MessageHandler实现。

      1. 设置userContentController的代理
    [self.webView.configuration.userContentController addScriptMessageHandler:self name:@"JSMessageToOC"];
    
    • 2.在js中,当需要给oc发消息的时候执行如下,这样是为了和安卓样式统一:
    window.webkit.messageHandlers.JSMessageToOC.postMessage("js发给oc的一条消息:aaa");
    
      1. self 遵守WKScriptMessageHandler协议, 实现方法。当js给oc发送消息的时候,该协议方法会被执行:
    - (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message{
           //通过message.name  message.body等获取消息。
    }
    

    2.注意循环引用问题:
    self引用webView。
    webView引用config。
    config引用contentController。
    contentController添加messageHandler为self来引用self。

    打破方式: messageHandler的对象使用代理。使用proxy等

    4.使用WebViewJavaScriptBridge.

    1.首先需要在js中写入如下代码

    function setupWebViewJavascriptBridge(callback) {
               if (window.WebViewJavascriptBridge) { return callback(WebViewJavascriptBridge); }
               if (window.WVJBCallbacks) { return window.WVJBCallbacks.push(callback); }
               window.WVJBCallbacks = [callback];
               var WVJBIframe = document.createElement('iframe');
               WVJBIframe.style.display = 'none';
               WVJBIframe.src = 'wvjbscheme://__BRIDGE_LOADED__';
               document.documentElement.appendChild(WVJBIframe);
               setTimeout(function() { document.documentElement.removeChild(WVJBIframe) }, 0)
           }
    

    2.js调用oc
    js给oc发消息方式如下:
    1.js中执行如下方法,将数据传给oc:

    WebViewJavascriptBridge.callHandler('jsCallsOC', {'argument': '18'}, function(response) {
      })
    

    2.oc执行如下方法,获取数据.

    • data中是js传给oc的消息,
    • oc还可以通过调用responseCallback 回应js.
    [self.bridge  registerHandler:@"jsCallsOC" handler:^(id data, WVJBResponseCallback responseCallback) {
            //js调用oc方法,oc执行后,可以调用responseCallback来通知js,oc执行完成了.
            NSLog(@"%@---%@",data,responseCallback);
        }];
    
    1. oc调用js方法,oc发消息给js
    2. oc中执行如下方法
    [self.wjb callHandler:@"OCCallJSFunction" data:@"data" responseCallback:^(id responseData) {
           //oc调用js方法,  js执行完成后,会回应oc 执行后的responseData.
            NSLog(@"%@",responseData);
        }];
    
    1. 在js中这样写:
      oc调用js,给js发消息时, js中方法会执行.
      data是oc给js的数据.
      js执行完成后,可以调用responsecallback来回应oc.
      //所有oc调用的js方法都需要在setup方法中注册.
      setupWebViewJavascriptBridge(function(bridge) {
           // JS 被调用的方法  OCCallJSFunction 定义的标识
           bridge.registerHandler('OCCallJSFunction', function(data,   responseCallback) {
                alert('JS方法被调用:'+data);             
                responseCallback('js执行过了');
           })
       })
    

    相关文章

      网友评论

          本文标题:1.WebView与OC通讯方式

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