iOS與JS(一):使用URL攔截的方式進行JS與OC互相調(diào)用

參考:

關(guān)于WKWebViewUIWebView之間的區(qū)別,本文就不在說明,本文只使用WKWebView。
效果圖如下:

html代碼:

<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf8">
        <script language="javascript">
            function loadURL(url) {
                window.location.href = url
            }
            
            function locationClick() {
                loadURL("scheme://getLocation");
            }
            
            function shake() {
                loadURL("scheme://shake");
            }
            
            function setLocation(location) {
                alert(location)
                document.getElementById("returnValue").value = location;
            }
            
        </script>
    </head>
    
    <body>
        <h1>這是按鈕調(diào)用</h1>
        <input type="button" value="獲取定位" onclick="locationClick()" /><br><br>
        <input type="button" value="震動一下" onclick="shake()" /><br><br>
        
        <h1>這是文件上傳</h1>
        <input type="file" /><br><br>
        
        <h1>這是回調(diào)結(jié)果展示區(qū)</h1>
        <textarea id ="returnValue" type="value" rows="5" cols="50"></textarea>
        
    </body>
</html>

以獲取定位這個按鈕為例說明OC和JS互相調(diào)用代碼執(zhí)行流程:

  1. 初始化WKWebView加載本地html文件。
  2. 點擊web中的按鈕,web發(fā)起URL請求。
  3. URL請求被WKNavigationDelegate中的代理方法攔截。根據(jù)自定義的URL識別使用不同的處理方式。如:在- (void)getLocation方法中調(diào)用JS的setLocation函數(shù)。
  4. JS的setLocation函數(shù)執(zhí)行JS的alert()函數(shù),被WKUIDelegate中的代理方法捕獲,調(diào)用iOS原生的彈框。

詳細代碼說明

  • 初始化WKWebView加載本地html文件

      - (void)initWKWebView
      {
          // 1
          WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init];
          configuration.userContentController = [WKUserContentController new];
          WKPreferences *preferences = [WKPreferences new];
          preferences.javaScriptCanOpenWindowsAutomatically = YES;
          preferences.minimumFontSize = 40.0;
          configuration.preferences = preferences;
          
          self.webView = [[WKWebView alloc] initWithFrame:self.view.frame configuration:configuration];
          
          // 2
          NSString *urlStr = [[NSBundle mainBundle] pathForResource:@"index.html" ofType:nil];
          NSURL *fileURL = [NSURL fileURLWithPath:urlStr];
          [self.webView loadFileURL:fileURL allowingReadAccessToURL:fileURL];
          
          self.webView.navigationDelegate = self;
          self.webView.UIDelegate = self;
          [self.view addSubview:self.webView];
      }
    
    • 1 WKWebView的一些參數(shù)配置
    • 2 加載本html
  • URL請求被WKNavigationDelegate中的代理方法攔截。也就是JS調(diào)用了OC

      #pragma mark - WKNavigationDelegate
      - (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler
      {
          NSURL *URL = navigationAction.request.URL;
          NSString *scheme = [URL scheme];
          if ([scheme isEqualToString:@"scheme"]) {
              
              [self handleCustomAction:URL];
              
              decisionHandler(WKNavigationActionPolicyCancel);
              return;
          }
          decisionHandler(WKNavigationActionPolicyAllow);
      }
    
  • OC 調(diào)用 JS

      - (void)getLocation
      {
          // 將結(jié)果返回給js
          NSString *jsStr = [NSString stringWithFormat:@"setLocation('%@')",@"上海市浦東新區(qū)"];
          [self.webView evaluateJavaScript:jsStr completionHandler:^(id _Nullable result, NSError * _Nullable error) {
              NSLog(@"%@----%@",result, error);
          }];
      }
    
    • JS代碼被當成字符串調(diào)用
    • completionHandler是JS代碼被調(diào)用后回調(diào)
  • JS中alert彈窗被WKUIDelegate中的代理方法捕獲,調(diào)用iOS原生的彈框。

      #pragma mark - WKUIDelegate
      - (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler
      {
          
          UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"提醒" message:message preferredStyle:UIAlertControllerStyleAlert];
          [alert addAction:[UIAlertAction actionWithTitle:@"知道了" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
              completionHandler();
          }]];
          
          [self presentViewController:alert animated:YES completion:nil];
      }
    

最后,html中的文件input可以直接調(diào)用iOS的圖片庫,相機和文件。

代碼: 90-iOSJS/OCJS1

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 通過本篇文章,至少可以學習到: OC如何給JS注入對象及JS如何給IOS發(fā)送數(shù)據(jù) JS調(diào)用alert、confir...
    一個叫小強的程序猿閱讀 1,213評論 2 0
  • 隨著H5技術(shù)的興起,在iOS開發(fā)過程中,難免會遇到原生應(yīng)用需要和H5頁面交互的問題。其中會涉及方法調(diào)用及參數(shù)傳值等...
    Chris_js閱讀 3,245評論 1 8
  • 1、加載網(wǎng)頁 WKWebView *webView = [[WKWebView alloc] initWithFr...
    LearningCoding閱讀 3,273評論 0 2
  • 明明在北郵人上找了學姐內(nèi)推,也收到郵件讓我完善簡歷了,但后來還是發(fā)短信讓我參加筆試,奇怪了,不管了,該走多少程序就...
    RAUL_AC閱讀 1,589評論 2 8
  • 感恩萬物 隨時有感恩的心 平安喜悅吉祥 改變命運的方法: 懺悔,寬恕,祈禱,感恩 女兒的種種問題都是因為自己做得不夠好
    Amy心靈之屋閱讀 222評論 0 0

友情鏈接更多精彩內(nèi)容