JS與原生OC/Swift相互調用總結

來源:互聯網
上載者:User

標籤:效果   cal   sel   web   注入   use   path   屬性   mac   

代碼地址如下:
http://www.demodashi.com/demo/12754.html

JS-OC-Swift

JS和OC/Swift相互調用,主要總結了JS和OC互動的三種方式

1.使用UIWebView,利用JavaScriptCore實現

2.使用WKWebView,利用WKScriptMessageHandler實現

3.使用第三方架構WebViewJavascriptBridge實現

部分

JavaScriptCore

JavaScriptCore介紹

JavaScriptCore架構是基於webkit中以C/C++實現的JavaScriptCore的一個封裝,該架構讓Objective-C和JavaScript代碼直接的互動變得更加的簡單方便,主要由下面幾個類組成。

1.JSContext
JS執行的環境,同時也通過JSVirtualMachine管理著所有對象的生命週期,每個JSValue都和JSContext相關聯並且強引用context。可以通過[webView valueForKeyPath:@”documentView.webView.mainFrame.javaScriptContext”]來從webview上擷取相應的JSContext。

2.JSValue
JS對象在JSVirtualMachine中的一個強引用,其實就是Hybird對象。我們對JS的操作都是通過它。並且每個JSValue都是強引用一個context。同時,OC和JS對象之間的轉換也是通過它。

3.JSManagedValue
JS和OC對象的記憶體管理輔助對象。由於JS記憶體管理是記憶體回收,並且JS中的對象都是強引用,而OC是引用計數。如果雙方相互引用,勢必會造成循環參考,而導致記憶體泄露。我們可以用JSManagedValue儲存JSValue來避免。

4.JSVirtualMachine
JS啟動並執行虛擬機器,有獨立的堆空間和記憶體回收機制。

5.JSExport
一個協議,如果JS對象想直接調用OC對象裡面的方法和屬性,那麼這個OC對象只要實現這個JSExport協議就可以了。

在Swift中擷取JS的context

context = webView.value(forKeyPath: "documentView.webView.mainFrame.javaScriptContext") as? JSContext

注入JS需要的對象,對象命名與html中使用的保持一致.self是遵守了JSExport協議,也可是其他遵守協議的對象。

context?.setObject(self, forKeyedSubscript:  "OC" as NSCopying & NSObjectProtocol)

JS調用Swift的方法,在Swift中實現協議

@objc protocol JSDelegate :JSExport {    //包含參數的func,需要注意參數名對函數名稱的影響    func showMessageToYou(_ message:String)        /*     對應html中“showAAndB”,此方法包含兩個參數,需要在參數前加“_”     func showA(_ aString: String, andB: String)     func showAAndB(_ aString:String,_ bStr:String)     以上兩個方法等同     */    func showAAndB(_ aString:String,_ bStr:String)        func doActionCallBack()}

Swift調用JS的方法

let jsStr = String(format:"callback(‘%@‘)",(textField?.text)!)self.context?.evaluateScript(jsStr)

OC中可使用block和實現JSExport協議兩種方式實現,代碼實現:

JSContext *context = [self.webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];self.context = context;//注入JS需要的“OC”對象,該對象與html中的保持一致即可self.context[@"OC"] = self;
WKScriptMessageHandler

初始化WKWebView後,添加供js調用oc/Swift的橋樑,這裡的name對應WKScriptMessage中的name

webView.configuration.userContentController.add(_ scriptMessageHandler: WKScriptMessageHandler, name: String)

遵守協議WKScriptMessageHandler,實現以下方法,可實現JS把訊息發送給OC/Swift。

func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage)

OC/Swift調用JS

let jsStr = String(format:"callback(‘%@‘)",(textField?.text)!)self.webView.evaluateJavaScript(jsStr as String, completionHandler: { (result:Any?, error:Error?) in       print("error:",error as Any) })
WebViewJavascriptBridge

WebViewJavascriptBridge是一個Objective-C與JavaScript進行訊息互連的第三方庫,可以很方便的實現OC和Javascript互調的功能。WebViewJavascriptBridge實現互調的過程也容易理解,就是在OC環境和Javascript環境各自儲存一個相互調用的bridge對象,每一個調用之間都有id和callbackid來找到兩個環境對應的處理。從Github上下載源碼之後,可以看到核心類主要包含如下幾個:

WebViewJavascriptBridge_JS:Javascript環境的Bridge初始化和處理。負責接收OC發給Javascript的訊息,並且把Javascript環境的訊息發送給OC。

WKWebViewJavascriptBridge/WebViewJavascriptBridge:主要負責OC環境的訊息處理,並且把OC環境的訊息發送給Javascript環境。

WebViewJavascriptBridgeBase:主要實現了OC環境的Bridge初始化和處理。

初始化WKWebViewJavascriptBridge

self.webViewBridge = [WKWebViewJavascriptBridge bridgeForWebView:self.webView];[self.webViewBridge setWebViewDelegate:self];

JS調用OC需要註冊事件

[self.webViewBridge registerHandler:@"handlerName" handler:^(id data, WVJBResponseCallback responseCallback) {   //code}];

OC調用JS

[self.webViewBridge callHandler:@"handlerName" data:@[textField.text] responseCallback:^(id responseData) {        NSLog(@"%@",responseData); }];

html中需要放置以下代碼

/*這段代碼是固定的,必須要放到js中*/function setupWebViewJavascriptBridge(callback) {    if (window.WebViewJavascriptBridge) { return callback(WebViewJavascriptBridge); }    if (window.WVJBCallbacks) { return window.WVJBCallbacks.push(callback); }    window.WVJBCallbacks = [callback];    var WVJBIframe = document.createElement(‘iframe‘);    WVJBIframe.style.display = ‘none‘;    WVJBIframe.src = ‘wvjbscheme://__BRIDGE_LOADED__‘;    document.documentElement.appendChild(WVJBIframe);    setTimeout(function() { document.documentElement.removeChild(WVJBIframe) }, 0)}/*與OC互動的所有JS方法都要放在此處註冊,才能調用通過JS調用OC或者讓OC調用這裡的JS*/setupWebViewJavascriptBridge(function(bridge) {     bridge.registerHandler(‘callback‘, function(data, responseCallback) {        callback(data);        responseCallback(‘js執行過了‘+data);    })})
項目結構

JS與原生OC/Swift相互調用總結

代碼地址如下:
http://www.demodashi.com/demo/12754.html

註:本文著作權歸作者,由demo大師代發,拒絕轉載,轉載需要作者授權

JS與原生OC/Swift相互調用總結

相關文章

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.