基于WKWebView的Hybrid容器初次實踐

實現思路

我的最終方案主要參考了豆瓣的rexxar和廣為大家使用的WebViewJavascriptBridge,之前也對后者有一點點研究

源碼實現

代碼暫時沒有考慮開源性,結合了部分公司的業務和個性化配置,不做提供了。

WKWebView一直有很多坑,而且蘋果也沒有要解決的意思。在性能和需求兩者中,一定要權衡利弊,謹慎使用。
創建一個WKWebView,會配置一些基本信息,主要是WKWebViewConfiguration,其中比較關鍵的一個是userContentController,它可以用于注入javascript腳本、處理nativeweb交互(本文后續都簡稱交互)等。

1)為什么要注入javascript
其實直接用WKWebView也能完成交互。客戶端直接調用evaluateJavaScript: completionHandler:方法,web端先在userContentController中調用addScriptMessageHandler方法注冊xxx事件,然后就可以用window.webkit.messageHandlers.xxx.postMessage(JSON.stringify(json))方法調用客戶端的方法了。(注意:xxx是要一一對應的)
當然,更好的推薦是使用WebViewJavascriptBridge,我們只要處理好注冊的事情就可以方便使用了,網上的教程也很多。

2)為什么不基于WebViewJavascriptBridge實現一個Hybrid容器?
最主要的目的:為了web端能用一份代碼實現與Android和iOS端的交互。(本文只是一種思路)

3)實現思路是什么?

  • a.使用WKWebView提供的交互方法,而不是用攔截URL Scheme的方式
  • b.將多個注冊事件統一為一個事件

第一點主要還是要結合Android端和iOS端的方案選擇。我們的Android端不使用攔截方式,所以我選擇了WKWebView的方法。
第二點是為了避免后期維護頻繁的添加新的事件。假如這個H5容器是一個開源庫,隨著業務擴展擴展,交互的事件越來越多。我們可以選擇把webView交付出去,讓用戶自身實現configuration的配置,注冊新的事件;也可以選擇提供API,讓用戶注冊新事件。但是,感覺這樣都不夠方便。
能否讓用戶只是單純的實現自己的業務方法,而不要考慮注冊的事情?
最終,采用的辦法是:只注冊一個事件,兩端的開發只需要商定交互的方法名,中間的事情都交給H5容器去做。具體的實現是:

  • a.假設注冊了一個InteractiveEvent
  • b.web端統一調用window.webkit.messageHandlers.InteractiveEvent.postMessage(msg)方法,參數msg中包含了需要調用方法的函數名、數據、回調等
  • c.客戶端拿到函數名,用NSMethodSignature提供的API生成最終的函數簽名
  • d.客戶端用一個哈希表存放了這些函數以及他們對應的組件功能,如果匹配上了則調用響應的功能。

小結

第一版做的比較簡單,基本是照葫蘆畫瓢,大部分的時間都用在填WKWebView的坑了,還好前人總結的非常全面。不過,新東西采坑是件好事,收獲很多。

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容