<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

       使用WKWebView的時候,如果想要實現(xiàn)JS調(diào)用OC方法,除了攔截URL之外,還有一種簡單的方式。那就是利用WKWebView的新特性MessageHandler來實現(xiàn)JS調(diào)用原生方法。

      MessageHandler 是什么?

      WKWebView 初始化時,有一個參數(shù)叫configuration,它是WKWebViewConfiguration類型的參數(shù),而WKWebViewConfiguration有一個屬性叫userContentController,它又是WKUserContentController類型的參數(shù)。WKUserContentController對象有一個方法- addScriptMessageHandler:name:,我把這個功能簡稱為MessageHandler。

      - addScriptMessageHandler:name:有兩個參數(shù),第一個參數(shù)是userContentController的代理對象,第二個參數(shù)是JS里發(fā)送postMessage的對象。
      所以要使用MessageHandler功能,就必須要實現(xiàn)WKScriptMessageHandler協(xié)議。
      我們在該API的描述里可以看到在JS中的使用方法:

      window.webkit.messageHandlers.<name>.postMessage(<messageBody>)
      //其中<name>,就是上面方法里的第二個參數(shù)`name`。
      //例如我們調(diào)用API的時候第二個參數(shù)填@"Share",那么在JS里就是:
      //window.webkit.messageHandlers.Share.postMessage(<messageBody>)
      //<messageBody>是一個鍵值對,鍵是body,值可以有多種類型的參數(shù)。
      // 在`WKScriptMessageHandler`協(xié)議中,我們可以看到mssage是`WKScriptMessage`類型,有一個屬性叫body。
      // 而注釋里寫明了body 的類型:
      Allowed types are NSNumber, NSString, NSDate, NSArray, NSDictionary, and NSNull.

      怎么使用MessageHandler?

      1.創(chuàng)建WKWebViewConfiguration對象,配置各個API對應的MessageHandler。

      WKUserContentController對象可以添加多個scriptMessageHandler。
      // 這是創(chuàng)建configuration 的過程
          WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init];
          WKPreferences *preferences = [WKPreferences new];
          preferences.javaScriptCanOpenWindowsAutomatically = YES;
          preferences.minimumFontSize = 40.0;
          configuration.preferences = preferences;
      - (void)viewDidLoad {
          [super viewDidLoad];
          // Do any additional setup after loading the view.
          self.webView.UIDelegate = self;
          self.webView.navigationDelegate = self;
          NSString *path = [[NSBundle mainBundle] pathForResource:@"test" ofType:@"html"];
          NSURL *url = [NSURL fileURLWithPath:path]; // [NSURL URLWithString:@"http://www.baidu.com"]; //
          
          NSURLRequest *request = [NSURLRequest requestWithURL:url];
          [self.webView loadRequest:request];
          // addScriptMessageHandler 很容易導致循環(huán)引用
          // 控制器 強引用了WKWebView,WKWebView copy(強引用了)configuration, configuration copy (強引用了)userContentController
          // userContentController 強引用了 self (控制器)
          [self.webView.configuration.userContentController addScriptMessageHandler:self name:@"clickYou"];
          
      }

      需要注意的是addScriptMessageHandler很容易引起循環(huán)引用,導致控制器無法被釋放,所以需要加入以下這段:

      - (void)viewWillDisappear:(BOOL)animated
      {
          [super viewWillDisappear:animated];
          
          // 因此這里要記得移除handlers
          [self.webView.configuration.userContentController removeScriptMessageHandlerForName:@"clickYou"];
      }

       

      2.實現(xiàn)協(xié)議方法。

      我這里實現(xiàn)了兩個協(xié)議<WKUIDelegate,WKScriptMessageHandler>WKUIDelegate是因為我在JS中彈出了alert 。WKScriptMessageHandler是因為我們要處理JS調(diào)用OC方法的請求。
      先看實現(xiàn)協(xié)議方法的示例代碼:

      - (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message{
          NSLog(@"%@:%@",message.name,message.body);
          if([message.name isEqualToString:@"clickYou"]){
              [self clickYou];
          }
      }

      WKScriptMessage有兩個關鍵屬性name 和 body
      因為我們給每一個OC 方法取了一個name,那么我們就可以根據(jù)name 來區(qū)分執(zhí)行不同的方法。body 中存著JS 要給OC 傳的參數(shù)。

      3.處理HTML中JS調(diào)用。

      function btnClick(){
          //JS調(diào)用
          window.webkit.messageHandlers.clickYou.postMessage({ "Acer": 500, "Dell": 600 });
          alert(1);
      }

      注意其中的clickYou,根據(jù)OC中注冊的name一樣.

       

      4.OC調(diào)用JS

      NSString *title = @"主題";
          NSString *content = @"內(nèi)容";
          NSString *url = @"http://www.baidu.com";
          NSString *jsStr = [NSString stringWithFormat:@"shareResult('%@','%@','%@')",title,content,url];
          [self.webView evaluateJavaScript:jsStr completionHandler:^(id _Nullable result, NSError * _Nullable error) {
              
          }];
      function shareResult(title,content,url){
          alert("title:"+title+"content:"+content+"url:"+url);
      }

       

      5.實現(xiàn)WKUIDelegate

      如果JS中需要alert,那么實現(xiàn)WKUIDelegate三個代理方法,如下:

      // alert框
      
      /**
       alert框
      
       @param webView WKWebView
       @param message 消息文本內(nèi)容
       @param frame frame主窗口
       @param completionHandler 窗口消失回調(diào)
       */
      - (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler{
          kFunLog
          UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"提示" message:message?:@"" preferredStyle:UIAlertControllerStyleAlert];
          [alertController addAction:([UIAlertAction actionWithTitle:@"確認" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
              completionHandler();
          }])];
          [self presentViewController:alertController animated:YES completion:nil];
      }
      
      // 確認框
      - (void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL result))completionHandler{
          kFunLog
          UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"提示" message:message?:@"" preferredStyle:UIAlertControllerStyleAlert];
          [alertController addAction:([UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
              completionHandler(NO);
          }])];
          [alertController addAction:([UIAlertAction actionWithTitle:@"確認" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
              completionHandler(YES);
          }])];
          [self presentViewController:alertController animated:YES completion:nil];
      }
      
      // 文本輸入框
      - (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(nullable NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString * _Nullable result))completionHandler{
          kFunLog
          UIAlertController *alertController = [UIAlertController alertControllerWithTitle:prompt message:@"" preferredStyle:UIAlertControllerStyleAlert];
          [alertController addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) {
              textField.text = defaultText;
          }];
          [alertController addAction:([UIAlertAction actionWithTitle:@"完成" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
              completionHandler(alertController.textFields[0].text?:@"");
          }])];
          
          [self presentViewController:alertController animated:YES completion:nil];
      }
      
      - (BOOL)webView:(WKWebView *)webView shouldPreviewElement:(WKPreviewElementInfo *)elementInfo API_AVAILABLE(ios(10.0)){
          return YES;
      }

       

      posted on 2017-11-14 14:38  HJiang  閱讀(2624)  評論(0)    收藏  舉報

      主站蜘蛛池模板: 成年无码av片在线蜜芽| 亚洲最大成人在线播放| 中文字幕在线视频不卡| 国产对白叫床清晰在线播放| 欧美人与动zozo在线播放| 亚洲av第一区二区三区| 男人j进入女人j内部免费网站| 大地资源中文第三页| 早起邻居人妻奶罩太松av| 欧洲免费一区二区三区视频| 精品国产免费第一区二区三区| 中文字幕一区二区精品区| 久久国产免费直播| 亚洲护士一区二区三区| 欧美亚洲人成网站在线观看| 国内少妇偷人精品免费| 国产精品国三级国产av| 久草热在线视频免费播放| 狠狠色丁香婷婷综合尤物| 欧洲免费一区二区三区视频| 国产av一区二区三区精品| 精品人妻无码一区二区三区| 亚洲熟妇熟女久久精品综合 | 延边| 亚洲精品三区四区成人少| 少妇又爽又刺激视频| 激情文学一区二区国产区| 国产午夜福利精品久久不卡| 日韩内射美女人妻一区二区三区| 蜜桃传媒av免费观看麻豆| 中文字幕亚洲无线码在线| 毛片内射久久久一区| 国产乱人激情H在线观看| 99国产精品一区二区蜜臀| 亚洲AVAV天堂AV在线网阿V | 中文字幕精品人妻丝袜| 久久精品国产亚洲精品色婷婷| 在线视频观看| 开心五月激情综合久久爱| 99久久精品美女高潮喷水| 中文字幕久久人妻熟人妻|