OC iOSとJSの相互作用(WebViewJavascriptBridge)

序文

最近iOS7オープンJavaScriptCoreにおけるフレームワークで使用されるリンゴの側面と対話知識OCを開発JS以前に使用したのUIWebView JSのOCの側面と対話するために、プロジェクトで使用され、使用することは非常に便利な、JavaScriptCoreにおけるソースコードが興味を持って、開いていますあなたは見つけるために行くことができます。

iOS8以来、アップルのUIWebViewのパフォーマンスが良くありません、我々はWKWebViewを立ち上げ、そして最もWKWebViewを両立させWebViewJavascriptBridge最新バージョン内のgithubの上の高得点します。

達成する方法

だから、道の私の概要は、のUIWebView、WKWebView、およびサードパーティWebViewJavascriptBridgeジェネリック版を指して、実現されました。

  • UIWebViewでJSのOCとの対話
  • JS OCでWKWebView(のみiOS8およびそれ以降のバージョン)との対話
  • UIWebViewのためWebViewJavascriptBridgeはWKWebViewプロセスに同意します。

WebViewJavascriptBridge

利点

  • 本質的に同じを使用してWKWebViewのUIWebView

  • 使用すると便利WebViewJavascriptBridge

  • AndroidのバージョンとiOS版WebViewJavascriptBridge、同じの実現とJSネイティブ相互作用は、何の両端が異なるコードに設定されていません

基本的な

  • OCとJSと通信するためにかなりの橋をWebViewJavascriptBridge。

  • JSをコールするようにOC方法は、ブリッジに登録されました。

  • JSブリッジへの登録方法、そのためOCを呼び出します。

下図のように誰が登録されていることは、と呼ばれるのを待っています。

15936146-2840fa7dce227602.png
WebViewJavascriptBridge回路図.PNG

手順を使用します

  • インポートWebViewJavaScriptBridgeプロジェクトの枠組み
pod ‘WebViewJavascriptBridge’

  • インポートヘッダファイル
#import <WebViewJavascriptBridge.h> 

  • 初期化WKWebView /のUIWebViewのプロキシ設定

    • それはのUIWebView UIWebViewDelegate設定されている場合

    • WKWebViewはその後WKNavigationDelegate、WKUIDelegateを設定した場合、

コードは以下の通りであります:

//初始化WKWebView
WKWebView *webView = [[WKWebView alloc] initWithFrame:self.view.bounds];
webView.navigationDelegate = self;
webView.UIDelegate = self;
[self.view addSubview:webView];

//或者初始化UIWebView
 UIWebView *webView = [[WKWebView alloc] initWithFrame:self.view.bounds];
webView.delegate = self;
[self.view addSubview:webView];   
 
  • WebViewのにJSとOjbC間のブリッジを構築
 self.bridge = [WebViewJavascriptBridge bridgeForWebView:webView];
[self.bridge setWebViewDelegate:self];

  • OC 2つのメソッドを登録し、JSコールウェイティング、responseCallback()の戻りjsのデータが通過しない場合があります

//registerHandler 注册,等着JS调用 responseCallback是返回js的数据
[self.bridge registerHandler:@"getUserIdFromObjC" handler:^(id data, WVJBResponseCallback responseCallback) {
        
    if (responseCallback) {
    
        responseCallback(@{@"userId":@"123456"});
   }
}];
    
//js调用的这个方法不需要给js反馈数据
[self.bridge registerHandler:@"notReturnFromJS" handler:^(id data, WVJBResponseCallback responseCallback) {
    
    NSLog(@"data -- %@",data);
}];

  • JSを呼び出し、イベントCLIK OnOCCallJSClickイベントを追加
- (void) OnOCCallJSClick:(id)sender {
    
    //这种调用js方式,不需要js在给返回值
    [self.bridge callHandler:@"getInfoFromJS" data:@{@"name":@"张三"}];
    
    //callHandler 调用JS  这个方式是,调用js,js有返回值的话,responseData就是js返回的
    [self.bridge callHandler:@"getInfoFromJS" data:@{@"name":@"张三"} responseCallback:^(id responseData) {
        
        
    }];
}

  • あなたは<SCRIPT> </ SCRIPT>内のHTMLを読み込むOC JSビルド橋を作ることができ、均一コードを記述する必要があります。
 <script>
      window.onerror = function(err) {
        log('window.onerror: ' + err)
      }
    
      /*这段代码是固定的,必须要放到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)
      }
    
      /*与OC交互的所有JS方法都要放在此处注册,才能调用通过JS调用OC或者让OC调用这里的JS*/
      setupWebViewJavascriptBridge(function(bridge) {
       var uniqueId = 1
       function log(message, data) {
         var log = document.getElementById('log')
         var el = document.createElement('div')
         el.className = 'logLine'
         el.innerHTML = uniqueId++ + '. ' + message + ':<br/>' + JSON.stringify(data)
         if (log.children.length) {
            log.insertBefore(el, log.children[0])
         } else {
           log.appendChild(el)
         }
       }
       
       /* Initialize your app here */
       
       /*我们在这注册一个js调用OC的方法,不带参数,
        *且不用ObjC端反馈结果给JS:打开本demo对应的博文
        */
       bridge.registerHandler('openWebviewBridgeArticle', function() {
                              
                              confirm("郭杨和小代是好朋友吗?");
          log("openWebviewBridgeArticle was called with by ObjC")
       })
       
      /*JS给ObjC提供公开的API,在ObjC端可以手动调用JS的这个API。
       *接收ObjC传过来的参数,且可以回调ObjC
       */
       bridge.registerHandler('getUserInfos', function(data, responseCallback) {
         log("Get user information from ObjC: ", data)
         responseCallback({'userId': '123456', 'blog': '标哥的技术博客'})
       })
                                   
      /*JS给ObjC提供公开的API,ObjC端通过注册,就可以在JS端调用此API时,得到回调。
       *ObjC端可以在处理完成后,反馈给JS,这样写就是在载入页面完成时就先调用
       */
    bridge.callHandler('getUserIdFromObjC', function(responseData) {
                    
         log("JS call ObjC's getUserIdFromObjC function, and js received response:", responseData)
       })
       
    })        
</script>
    
  • JSはまた、この方法でOCを待って呼び出すための登録方法をregisterHandlerを持っています

  • JS callHandlerのように、OCのメソッドを呼び出すには

  • JS responseCallbackデータは、OC、OCは合格しない場合があります返さresponseCallbackは空です

注意を払います

あなたがWebViewJavascriptBridgeを達成するためにWKWebviewを使用している場合は、まだプロンプトポップアップボックスがブロックされたコールシステム、警報を、確認するので、私たちはネイティブの傍受後の三つの方法UIDelegateプロキシ、ポップポップアップボックスを実装する必要があります

#pragma mark - WKUIDelegate

//! alert(message)
- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler {
    
    UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"Alert" message:message preferredStyle:UIAlertControllerStyleAlert];
    UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
        completionHandler();
    }];
    [alertController addAction:cancelAction];
    [self presentViewController:alertController animated:YES completion:nil];
}

//! confirm(message)
- (void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL))completionHandler {
    
    UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"Confirm" message:message preferredStyle:UIAlertControllerStyleAlert];
    UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
        completionHandler(NO);
    }];
    UIAlertAction *confirmAction = [UIAlertAction actionWithTitle:@"确认" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
        completionHandler(YES);
    }];
    [alertController addAction:cancelAction];
    [alertController addAction:confirmAction];
    [self presentViewController:alertController animated:YES completion:nil];
}

//! prompt(prompt, defaultText)
- (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString *))completionHandler {
    
    UIAlertController *alertController = [UIAlertController alertControllerWithTitle:prompt message:nil preferredStyle:UIAlertControllerStyleAlert];
    [alertController addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) {
        textField.placeholder = defaultText;
    }];
    UIAlertAction *confirmAction = [UIAlertAction actionWithTitle:@"确认" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
        completionHandler(alertController.textFields[0].text);
    }];
    [alertController addAction:confirmAction];
    [self presentViewController:alertController animated:YES completion:nil];
}

エンディング

より便利に使い、パスの一端限り、デバッグをAndroidのフロントエンドの両方を避けるだけでなく、iOS版と書かれたJSのOCの相互作用を記述するために、使用されているWebViewJavascriptBridge、すべてのAndroidとiOSのAndroidのバージョンがありますWebViewJavascriptBridge 、JSは、iOSとAndroidを使用すると、iOSのアンドリュースの問題を解決することがありさまざまな問題を持っているので、団結がより重要である、そこではない、問題には何もないはずなトラブルシューティングを容易にします。(一部が不十分ください批判や満足感を持っているとして、その後~~~賞賛を与えます)

おすすめ

転載: blog.csdn.net/weixin_34408717/article/details/90932309