WebViewJavascriptBridge解讀

要知道的事

ios的webview有2個(gè)類(lèi),一個(gè)叫UIWebView,另一個(gè)是WKWebView。WKWebView是取代UIWebView出現(xiàn)的,在app開(kāi)發(fā)者若不需要兼容ios8之前版本,都應(yīng)該使用WKWebVIew。

WKWebView 是蘋(píng)果在 iOS 8 中引入的新組件,目的是給出一個(gè)新的高性能的 Web View 解決方案,擺脫過(guò)去 UIWebView 的老舊笨重特別是內(nèi)存占用量巨大的問(wèn)題,它使用Nitro JavaScript引擎,這意味著所有第三方瀏覽器運(yùn)行JavaScript將會(huì)跟safari一樣快.

UIWebView使用

app調(diào)用js:?webView.stringByEvaluatingJavaScriptFromString()?

js調(diào)用app:

UIWebView沒(méi)有辦法直接使用js調(diào)用app,但是可以通過(guò)攔截request的方式間接實(shí)現(xiàn)js調(diào)用app方法。

在網(wǎng)頁(yè)中加載一個(gè) Custom URL Scheme 的鏈接(直接設(shè)置 window.location 或者新建一個(gè) iframe 去加載這個(gè) URL),原生中攔截?UIWebView?的代理方法 - webView:shouldStartLoadWithRequest:navigationType:,然后根據(jù)約定好的協(xié)議做相應(yīng)的處理。

app調(diào)js可以有返回值,但是js調(diào)app是通過(guò)間接的攔截request方式實(shí)現(xiàn),它根本就不算方法調(diào)用,所以應(yīng)該是不存在可以直接產(chǎn)生返回值的

WKWebView使用

app調(diào)用js:WKWebView調(diào)用js方法和UIWebView類(lèi)似,一個(gè)是evaluateJavaScript,一個(gè)是stringByEvaluatingJavaScriptFromString。獲取返回值的方式不同,WKWebView用的是回叫函數(shù)block獲取返回值

js調(diào)用app:

1. 間接的攔截request方式實(shí)現(xiàn),攔截WKWebView代理方法:

- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler

2.?引用??蘋(píng)果在 WKWebView 中的 js runtime 里事先注入了一個(gè) window.webkit.messageHandlers.OOXX.postMessage() 方法,我們可以使用這個(gè)方法直接向 Native 層傳值,異常方便。 ?

WebViewJavascriptBridge源碼解讀

WebViewJavascriptBridgeBase:① 用來(lái)進(jìn)行 bridge 初始化和消息處理的核心類(lèi);② 這個(gè)類(lèi)是在支持?WKWebView?后從??WebViewJavascriptBridge?中獨(dú)立出來(lái)的邏輯,專(zhuān)門(mén)用來(lái)處理 bridge 相關(guān)的邏輯,不再與具體的 Web View 相關(guān)聯(lián)了

WebViewJavascriptBridge:① 橋接的入口,針對(duì)不同類(lèi)型的 Web View (UIWebView、WKWebView、WebView)進(jìn)行分發(fā);② 針對(duì)?UIWebView?和?WebView?做的一層封裝,主要用來(lái)執(zhí)行 JS 代碼,以及實(shí)現(xiàn)?UIWebView?和?WebView的代理方法,并通過(guò)攔截 URL 來(lái)通知?WebViewJavascriptBridgeBase?做相應(yīng)操作

WKWebViewJavascriptBridge:針對(duì)?WKWebView?做的一層封裝,主要用來(lái)執(zhí)行 JS 代碼,以及實(shí)現(xiàn)?WKWebView?的代理方法,并通過(guò)攔截 URL 來(lái)通知?WebViewJavascriptBridgeBase?做相應(yīng)操作

WebViewJavascriptBridge_JS:JS 端負(fù)責(zé)“收發(fā)消息”的代碼

主要流程

一、初始化

(1)?Objective-C 中的初始化

初始化 UIWebView;初始化 WebViewJavascriptBridge,設(shè)置 web view 代理;初始化 WebViewJavascriptBridgeBase,初始化相關(guān)的屬性

(2)?注冊(cè) handler 供 JS 調(diào)用——把注冊(cè)過(guò)的 handler 保存起來(lái) :

[self.bridge registerHandler:@"share" handler:^(id data, WVJBResponseCallback responseCallback) { }];

(3)?Objective-C 中通過(guò)調(diào)用?UIWebView?的?loadRequest:?方法加載 網(wǎng)頁(yè)URL

(4)?網(wǎng)頁(yè)一加載就會(huì)執(zhí)行 web 頁(yè)中的 bridge 初始化代碼,也就是調(diào)用上面提到的?setupWebViewJavascriptBridge(bridge)函數(shù):

1》保存要執(zhí)行的自定義初始化函數(shù),比如注冊(cè) JS 中的 handler;

2》通過(guò)添加一個(gè) iframe 加載初始化鏈接?https://__bridge_loaded__

(5)?原生 WebViewJavascriptBridge 類(lèi)中代理方法會(huì)攔截?https://__bridge_loaded__?的加載,在 web view 中執(zhí)行本地 WebViewJavascriptBridge_JS.m 文件中的代碼,初始化?window.WebViewJavascriptBridge對(duì)象:

1》在 JS 中創(chuàng)建一個(gè)?WebViewJavascriptBridge?對(duì)象,并設(shè)置成?window?的一個(gè)屬性;

2》定義幾個(gè)用于管理消息的全局變量;

3〉給?WebViewJavascriptBridge?對(duì)象定義幾個(gè)處理消息的方法和函數(shù);

4》執(zhí)行原生端?startupMessageQueue?中保存的消息,也就是本地 JS 文件還未加載時(shí)就發(fā)送了的消息

(6)?初始化完畢

二、JS調(diào)用OC

WebViewJavascriptBridgeBase中JS調(diào)用OC方法關(guān)鍵代碼:

三、OC調(diào)用JS

WebViewJavascriptBridge_JS中OC調(diào)用JS方法關(guān)鍵代碼:

參考鏈接:

WebViewJavascriptBridge 從原理到實(shí)戰(zhàn)

UIWebView和WKWebView的使用及js交互

js 向 Native 一句話(huà)傳值

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

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

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