iOS下JS與OC互相調用(二)--WKWebView 攔截URL

來源:互聯網
上載者:User

標籤:執行   類型   canopen   orm   沒有   推出   返回   記憶體   decide   

在第一篇文章 iOS下JS與OC互相調用(一)中講述了使用UIWebView攔截URL的方式來處理JS與OC互動。 由於UIWebView比較耗記憶體,效能上不太好,而蘋果在iOS 8中推出了WKWebView。 同樣的用WKWebView也可以攔截URL,做JS 與OC互動。關於WKWebView與UIWebView的對比,大家請自動百度或者google。

WKWebView 攔截URL

WKWebView 與 UIWebView 攔截URL 的處理方式基本一樣。除了代理方法和WKWebView的使用不太一樣,關於WKWebView更詳盡的講解和用法,還是自行搜尋學習,本文重點還是講解如何?JS 與OC 互相調用,WKWebView 是iOS 8 推出的WebKit.framework中的控制項,只有app 不需要相容iOS 7及以下的時候才可以使用。感謝Haley_Wong大神提供資源.

1.建立WKWebView,載入本地HTML。 WKWebView的建立有幾點不同:1.初始化多了個configuration參數,當然這個參數我們也可以不傳,直接使用預設的設定就好。2.WKWebView的代理有兩個navigationDelegate和UIDelegate。我們要攔截URL,就要通過navigationDelegate的一個代理方法來實現。如果在HTML中要使用alert等彈窗,就必須得實現UIDelegate的相應代理方法。3.在iOS 9之前,WKWebView載入本地HTML會有一些問題。(不能載入本地HTML,或者部分CSS/本地圖片載入不了等) 我這裡建立WKWebView的範例程式碼是這樣的:
WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init];    configuration.userContentController = [WKUserContentController new];    WKPreferences *preferences = [WKPreferences new];    preferences.javaScriptCanOpenWindowsAutomatically = YES;    preferences.minimumFontSize = 30.0;    configuration.preferences = preferences;    self.webView = [[WKWebView alloc] initWithFrame:self.view.frame configuration:configuration];    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.view addSubview:self.webView];
2.攔截URL

使用WKNavigationDelegate中的代理方法,攔截自訂的URL來實現JS調用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:@"haleyaction"]) {        [self handleCustomAction:URL];        decisionHandler(WKNavigationActionPolicyCancel);        return;    }    decisionHandler(WKNavigationActionPolicyAllow);}

需要注意的是:

1.如果實現了這個代理方法,就必須得調用decisionHandler這個block,否則會導致app 崩潰。block參數是個枚舉類型,WKNavigationActionPolicyCancel代表取消載入,相當於UIWebView的代理方法return NO的情況;WKNavigationActionPolicyAllow代表允許載入,相當於UIWebView的代理方法中 return YES的情況。 2.其他的關於為什麼要統一設定scheme,在上一篇中講過。

關於如何區分執行不同的OC 方法,也與UIWebView的處理方式一樣,通過URL 的host 來區分執行不同的方法:
#pragma mark - private method- (void)handleCustomAction:(NSURL *)URL{    NSString *host = [URL host];    if ([host isEqualToString:@"scanClick"]) {        NSLog(@"掃一掃");    } else if ([host isEqualToString:@"shareClick"]) {        [self share:URL];    } else if ([host isEqualToString:@"getLocation"]) {        [self getLocation];    } else if ([host isEqualToString:@"setColor"]) {        [self changeBGColor:URL];    } else if ([host isEqualToString:@"payAction"]) {        [self payAction:URL];    } else if ([host isEqualToString:@"shake"]) {        [self shakeAction];    } else if ([host isEqualToString:@"goBack"]) {        [self goBack];    }}
3.OC 調用 JS 方法

JS 調用OC 方法後,有的操作可能需要將結果返回給JS。這時候就是OC 調用JS 方法的情境。
WKWebView 提供了一個新的方法evaluateJavaScript:completionHandler:,實現OC 調用JS 等情境。

- (void)getLocation{    // 擷取位置資訊    // 將結果返回給js    NSString *jsStr = [NSString stringWithFormat:@"setLocation(‘%@‘)",@"廣東省深圳市"];    [self.webView evaluateJavaScript:jsStr completionHandler:^(id _Nullable result, NSError * _Nullable error) {        NSLog(@"%@----%@",result, error);    }];}

evaluateJavaScript:completionHandler:沒有傳回值,JS 執行成功還是失敗會在completionHandler 中返回。所以使用這個API 就可以避免執行耗時的JS,或者alert 導致介面卡住的問題。

4.WKWebView中使用彈窗

在上面提到,如果在WKWebView中使用alert、confirm 等彈窗,就得實現WKWebView的WKUIDelegate中相應的代理方法。
例如,我在JS中要顯示alert 彈窗,就必須實現如下代理方法,否則alert 並不會彈出。

#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];}

其中completionHandler這個block 一定得調用,至於在哪裡調用,倒是無所謂,我們也可以寫在方法實現的第一行,或者最後一行。

 

demo地址:https://github.com/domanc/JS-OC-URL.git

iOS下JS與OC互相調用(二)--WKWebView 攔截URL

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.