VUE 與 原生交互(iOS為主)

使用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的使用

// 這是創(chuàng)建configuration 的過程
    WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init];
    WKPreferences *preferences = [WKPreferences new];
    preferences.javaScriptCanOpenWindowsAutomatically = YES;
    preferences.minimumFontSize = 40.0;
    configuration.preferences = preferences;
    

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    // addScriptMessageHandler 很容易導(dǎo)致循環(huán)引用
    // 控制器 強引用了WKWebView,WKWebView copy(強引用了)configuration, configuration copy (強引用了)userContentController
    // userContentController 強引用了 self (控制器)
    [self.webView.configuration.userContentController addScriptMessageHandler:self name:@"GoBack"];
    [self.webView.configuration.userContentController addScriptMessageHandler:self name:@"Share"];
}
//需要注意的是addScriptMessageHandler很容易引起循環(huán)引用,導(dǎo)致控制器無法被釋放,所以需要加入以下這段:
- (void)viewWillDisappear:(BOOL)animated
{
    [super viewWillDisappear:animated];
    
    // 因此這里要記得移除handlers
    [self.webView.configuration.userContentController removeScriptMessageHandlerForName:@"Shake"];
    [self.webView.configuration.userContentController removeScriptMessageHandlerForName:@"GoBack"];
}

WKScriptMessageHandler的代理實現(xiàn)

#pragma mark - WKScriptMessageHandler
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message
{
//    message.body  --  Allowed types are NSNumber, NSString, NSDate, NSArray,NSDictionary, and NSNull.
  if ([message.name isEqualToString:@"Shake"]) {
         NSLog(@"分享");
    } else if ([message.name isEqualToString:@"GoBack"]) {
         NSLog(@"返回");
    }
}

JS調(diào)iOS原生方法

const u = navigator.userAgent;
//android終端
const isAndroid = u.indexOf('Android') > -1 || u.indexOf('Adr') > -1;
// IOS終端
const isiOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/);

 if (isiOS) {<!-- -->
  window.webkit.messageHandlers.GoBack.postMessage('');//getUserId.postMessage('')為IOS定義的原生方法
 //你的邏輯代碼
 } else if (isAndroid) {<!-- -->
  window.java_obj.GoBack() //java_obj.getUserId()為安卓定義的方法,具體方法名可與其溝通
 // 你的邏輯代碼
 }
?著作權(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)容

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