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

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

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

      iOS WKWebView OC 與 JS 交互學習

      我寫WKWebView 想讓 服務端相應 一個 方法但是不響應,根據 UIWebView 用 JSContext就能拿到響應的處理經驗是不是服務端 也需要 對 WKwebView有兼容的一個寫法??? 特此學習 WKWebView 記錄

      一 .WKWebView 代理協議

      (1)WKScriptMessageHandler :

      OC在JS調用方法時做的處理。如果需要調用對話窗口就會先執行(3)協議再執行 (1)協議

      好處:傳遞給OC的參數直接在字典里面,不用再在url里面拼湊后的結果去截取解析。

      必須實現

      - (void)userContentController:(WKUserContentController *)userContentController
            didReceiveScriptMessage:(WKScriptMessage *)message

      (2)WKNavigationDelegate:

      處理頁面跳轉和載入過程。

      #pragma mark -- 進行頁面跳轉
      
      // 接收到服務器跳轉請求之后再執行
      - (void)webView:(WKWebView *)webView didReceiveServerRedirectForProvisionalNavigation:(null_unspecified WKNavigation *)navigation;
      // 在發送請求之前,決定是否跳轉
      - (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler ;
      // 在收到響應后,決定是否跳轉
      - (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler ;
      #pragma mark -- 追蹤加載過程
      
      // 頁面開始加載時調用
      - (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(null_unspecified WKNavigation *)navigation;
      
      // 當內容開始返回時調用
      - (void)webView:(WKWebView *)webView didCommitNavigation:(null_unspecified WKNavigation *)navigation;
      // 頁面加載完成之后調用
      - (void)webView:(WKWebView *)webView didFinishNavigation:(null_unspecified WKNavigation *)navigation;
      // 頁面加載失敗時調用
      - (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(null_unspecified WKNavigation *)navigation withError:(NSError *)error;
      
      //好多協議 按需添加。。。

      (3)WKUIDelegate

      這個協議主要用于WKWebView處理web界面的三種提示框(警告框、確認框、輸入框) 的網頁交互

      #pragma mark - WKUIDelegate
      //警告
      - (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler;
      //確認
      - (void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL result))completionHandler;
      // 輸入框
      - (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(nullable NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString * __nullable result))completionHandler;

      二.協議使用

      (1)WKScriptMessageHandler ,關鍵在當前頁面銷毀后要注銷協議保證無強引用,當前頁面也無法銷毀,發生內存泄漏。

      //注冊協議
          self.userContentController = [[WKUserContentController alloc] init];
          //注冊方法
          WKDelegateController *delegateController = [[WKDelegateController alloc]init];
          delegateController.delegate = self;
          
          // 通過JS與webview內容交互
          config.userContentController = self.userContentController;
          // 注入JS對象名稱HFAlert,HFConfirm,HFPrompt當JS通過HFAlert,HFConfirm,HFPrompt來調用時,
          // 我們可以在WKScriptMessageHandler代理中接收到
          [config.userContentController addScriptMessageHandler:delegateController name:HFAlert];
          [config.userContentController addScriptMessageHandler:delegateController name:HFConfirm];
          [config.userContentController addScriptMessageHandler:delegateController name:HFPrompt];
          [config.userContentController addScriptMessageHandler:delegateController name:HFShare];
      //注銷協議
      - (void)dealloc
      {
          [self.userContentController removeScriptMessageHandlerForName:HFAlert];
          [self.userContentController removeScriptMessageHandlerForName:HFConfirm];
          [self.userContentController removeScriptMessageHandlerForName:HFPrompt];
          [self.userContentController removeScriptMessageHandlerForName:HFShare];
      }
      //實施協議
      - (void)userContentController:(WKUserContentController *)userContentController
            didReceiveScriptMessage:(WKScriptMessage *)message {
          NSLog(@"%@", message.body);
          if ([message.name isEqualToString:HFAlert]) {
              // 打印所傳過來的參數,只支持NSNumber, NSString, NSDate, NSArray,
              // NSDictionary, and NSNull類型
              NSDictionary *dictionary = message.body;
              if (![dictionary isKindOfClass:[NSDictionary class]]) {
                  return;
              }
              NSLog(@"%@",dictionary[@"body"]); //服務端傳值 log
              dispatch_async(dispatch_get_main_queue(), ^{
                  //主線程操作UI
              });
          } else if ([message.name isEqualToString:HFConfirm]) {
              
          } else if ([message.name isEqualToString:HFPrompt]) {
              
          } else if ([message.name isEqualToString:HFShare]) {
          
          }
      }
      設置代理 WKDelegateController 重寫成代理控制器性質,保證設置代理后,可移除 的關鍵!!!
      //
      //  WKDelegateController.m
      //  SectionDemo
      //
      //  Created by HF on 2017/6/22.
      //  Copyright ? 2017年 HF-Liqun. All rights reserved.
      //
      
      #import "WKDelegateController.h"
      
      @interface WKDelegateController ()
      
      @end
      
      @implementation WKDelegateController
      
      - (void)viewDidLoad {
          [super viewDidLoad];
      }
      
      - (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message{
          if ([self.delegate respondsToSelector:@selector(userContentController:didReceiveScriptMessage:)]) {
              [self.delegate userContentController:userContentController didReceiveScriptMessage:message];
          }
      }
      @end
      ////////
      //
      //  WKDelegateController.h
      //  SectionDemo
      //
      //  Created by HF on 2017/6/22.
      //  Copyright ? 2017年 HF-Liqun. All rights reserved.
      //
      
      #import <UIKit/UIKit.h>
      #import <WebKit/WebKit.h>
      
      @protocol WKDelegate <NSObject>
      
      - (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message;
      
      @end
      
      @interface WKDelegateController : UIViewController <WKScriptMessageHandler>
      
      @property (weak , nonatomic) id < WKScriptMessageHandler > delegate;
      
      @end

      (2)WKNavigationDelegate,舉例子和UIWebView shouldStart  方法一樣,在請求前判斷要不要繼續執行

      // 在發送請求之前,決定是否跳轉
      - (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
          NSString *hostname = navigationAction.request.URL.host.lowercaseString;
          if (navigationAction.navigationType == WKNavigationTypeLinkActivated
              && ![hostname containsString:@".baidu.com"]) {
              // 對于跨域,需要手動跳轉
              [[UIApplication sharedApplication] openURL:navigationAction.request.URL];
              
              // 不允許web內跳轉
              decisionHandler(WKNavigationActionPolicyCancel);
          } else {
              self.progressView.alpha = 1.0;
              decisionHandler(WKNavigationActionPolicyAllow);
          }
          NSLog(@"%s", __FUNCTION__);
      }

      (3)WKUIDelegate  參考代碼

      #pragma mark - WKUIDelegate 這個協議主要用于WKWebView處理web界面的三種提示框(警告框、確認框、輸入框) 的網頁交互/**
       *  web界面中有彈出警告框時調用
       *
       *  @param webView           實現該代理的webview
       *  @param message           警告框中的內容
       *  @param frame             主窗口
       *  @param completionHandler 警告框消失調用 無回調
       */
      
      - (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler {
          NSLog(@"%s", __FUNCTION__);
          //completionHandler(@"空回調");
          UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"alert" message:[NSString stringWithFormat:@"JS調用alert message:%@",message] preferredStyle:UIAlertControllerStyleAlert];
          [alert addAction:[UIAlertAction actionWithTitle:@"確定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
              completionHandler();
          }]];
          
          [self presentViewController:alert animated:YES completion:NULL];
          NSLog(@"%@", message);
      }
      
      
      /**
       確認框
       
       @param webView 實現該代理的webview
       @param message 確認窗口內容
       @param frame 主窗口
       @param completionHandler 警告框消失調用 回傳布爾變量
       */
      - (void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL result))completionHandler {
          NSLog(@"%s", __FUNCTION__);
          
          //completionHandler(@"可以直接回傳布爾變量");
          UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"confirm" message:@"JS調用confirm" 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];
          
          NSLog(@"%@", message);
      }
      
      
      /**
       輸入框
       
       @param webView web
       @param prompt 文本
       @param defaultText 默認輸入文本
       @param frame frame
       @param completionHandler completionHandler  回傳 字符串
       */
      - (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(nullable NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString * __nullable result))completionHandler {
          
          //completionHandler(@"可以直接回傳字符串");
          //可以根據回傳參數來判斷 是否必要展示 彈框,也可以隱式處理 根據當前參數判斷回傳指定邏輯參數
          NSLog(@"%s", __FUNCTION__);
          NSLog(@"%@", prompt);
          if ([prompt isEqualToString:HFPrompt]) {
              completionHandler(@"guess");
              return;
          }
          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];
      }

      三.OC JS 互相調用

      (1)  OC 調用 JS 代碼(OC注入JS)

              NSString *js = @"alertName('我是參數')";//可以向js傳參數
      //NSString *js = @"callJsAlert()";//無參數方法 [self.webView evaluateJavaScript:js completionHandler:^(id _Nullable response, NSError * _Nullable error) { NSLog(@"response: %@ error: %@", response, error); NSLog(@"call js alert by native"); }];

       

       

      (2) JS 調用 OC方法:關鍵是按照約定方法名和注冊名

      關鍵代碼: 

      //name 為注冊名 HFAlert HFPrompt ...  messageBody 為傳遞參數集合 和 UIWebView的 調用OC 方法 是不一樣的!!!!!
      window.webkit.messageHandlers.<name>.postMessage(<messageBody>);

      參考示例:

      <!DOCTYPE html>
      <html>
        <head>
          <title>iOS and Js</title>
          <style type="text/css">
            * {
              font-size: 40px;
            }
          </style>
        </head>
        
        <body>
          
          <div style="margin-top: 100px">
            <h1>Test how to use objective-c call js</h1><br/><br/>
            <div><input type="button" value="call shareButton" onclick="shareClick()"></div>
            <br/><br/>
            <div><input type="button" value="call js alert" onclick="callJsAlert()"></div>
            <br/>
            <div><input type="button" value="Call js confirm" onclick="callJsConfirm()"></div><br/>
          </div>
          <br/>
          <div>
            <div><input type="button" value="Call Js prompt " onclick="callJsInput()"></div><br/>
            <div>Click me here: <a href="http://www.baidu.com">Jump to Baidu</a></div>
          </div>
          
          <br/>
          <div id="SwiftDiv">
            <span id="jsParamFuncSpan" style="color: red; font-size: 50px;"></span>
          </div>
          
          <script type="text/javascript">
            //JS執行window.webkit.messageHandlers.Share.postMessage(<messageBody>)
            function callJsAlert() {
              //WKUIDelegate 空回調 警告框代理被觸發
              alert('Objective-C call js to show alert');
              // HFAlert是我們所注入的對象
              window.webkit.messageHandlers.HFAlert.postMessage({body: 'call js alert in js'});
            }
          
            function callJsConfirm() {
              //WKUIDelegate 布爾回調 選擇確認框代理被觸發
              if (confirm('confirm', 'Objective-C call js to show confirm')) {
              document.getElementById('jsParamFuncSpan').innerHTML
              = 'true';
            } else {
              document.getElementById('jsParamFuncSpan').innerHTML
              = 'false';
            }
            
            //HFConfirm是我們所注入的對象
            window.webkit.messageHandlers.HFConfirm.postMessage({body: 'call js confirm in js'});
          }
          
          function callJsInput() {
            //WKUIDelegate 字符串回調 輸入框代理被觸發
            var response = prompt('HFPrompt', 'Please input your name:');
            document.getElementById('jsParamFuncSpan').innerHTML = response;
            
             //HFPrompt是我們所注入的對象
            window.webkit.messageHandlers.HFPrompt.postMessage({body: response});
          }
          
          function shareClick() {
              var response = prompt('Hello');
              window.webkit.messageHandlers.HFShare.postMessage({body:response ,title:'測試分享的標題',content:'測試分享的內容',url:'https://github.com/maying1992'});
          }
      
          function alertName(msg) {
              document.getElementById('jsParamFuncSpan').innerHTML = 'name' + msg + ', nice to meet you';
          }
            </script>
        </body>
      </html>

      end

       

      參考 

      (1) http://www.tuicool.com/articles/qQRrMzY

      (2)http://www.cocoachina.com/ios/20160906/17487.html

      (3)http://www.jianshu.com/p/4fa8c4eb1316

      (4)http://blog.csdn.net/u011619283/article/details/52135988

       

      posted on 2017-06-22 18:02  ACM_Someone like you  閱讀(6536)  評論(0)    收藏  舉報

      導航

      主站蜘蛛池模板: 环江| 亚洲精品无码成人A片九色播放| 亚洲成人四虎在线播放| 亚洲中文久久久精品无码| 国产精品免费视频不卡| 国产精品美腿一区在线看| 亚洲国产精品第一二三区| 午夜在线不卡| 亚洲精品宾馆在线精品酒店| 最新国产AV最新国产在钱| 国产精品国语对白一区二区| 亚洲国产精品成人一区二区在线 | 久久99亚洲网美利坚合众国| 国产高清在线精品一本大道| 国产日韩精品欧美一区灰| 亚洲欧美日韩愉拍自拍美利坚| 精品一区二区三区东京热| 亚洲av一本二本三本| 乱人伦人妻中文字幕无码久久网| 粗大挺进朋友人妻淑娟| 日本丰满白嫩大屁股ass| 亚洲精品综合一区二区在线| 亚洲精品中文字幕第一页| 男女扒开双腿猛进入爽爽免费看| 午夜成人性爽爽免费视频| 日韩在线一区二区每天更新| 中文字幕第55页一区| 好男人官网资源在线观看| 亚洲 日韩 国产 制服 在线| 久久综合色天天久久综合图片| 五河县| 91精品乱码一区二区三区| 一区二区三区精品不卡| 性欧美乱熟妇xxxx白浆| 国产91精品调教在线播放| 午夜一区二区三区视频| 国产在线精品第一区二区| 亚洲 日本 欧洲 欧美 视频| 偷拍美女厕所尿尿嘘嘘小便| 国产福利午夜十八禁久久| 国产成人午夜精品福利|