寫一個(gè)易于維護(hù)使用方便性能可靠的Hybrid框架(四)—— 框架構(gòu)建

image

前言

基于前面的三篇,我們的Hybird框架基本搭建完成了莉测,本篇在《寫一個(gè)易于維護(hù)使用方便性能可靠的Hybrid框架(三)—— 配置插件》的基礎(chǔ)上做了一些優(yōu)化颜骤,后續(xù)又做了UIWebView的兼容。當(dāng)下的跨平臺方案很多捣卤,weex忍抽、RNflutter層出不窮。那么對于WebView的探究是否仍有必要董朝?實(shí)際上我們可以探究一下他們的根本梯找,或許就不會有疑惑了∫娼В跨平臺方案旨在節(jié)約成本,快速更新迭代驯鳖,甚至達(dá)到熱更新的能力闲询。那么WebView面向的是誰呢,是整個(gè)前端開發(fā)者浅辙,構(gòu)建web應(yīng)用目前來看依舊是效率最快扭弧、范圍最廣、熱更新能力最強(qiáng)的不二之選记舆。市面上的App幾乎都無法逃離WebView鸽捻,從《支付寶移動端動態(tài)化方案實(shí)踐》可以看出,支付寶也有一套自己的解決方案Nebula 框架泽腮,其實(shí)不止支付寶御蒲,所有的App自始至終都會有一套自己的WebView框架,與前面提到的跨端技術(shù)并不沖突诊赊,屬于并駕齊驅(qū)厚满。

那么今天要說的就是如何構(gòu)建一個(gè)WebView的Hybrid框架,并讓它獨(dú)立于項(xiàng)目中碧磅,像AFN碘箍、SD一樣存在于你的項(xiàng)目中,也并不會關(guān)聯(lián)你的業(yè)務(wù)鲸郊,像支付寶的Nebula一樣丰榴,讓它成為你項(xiàng)目組件的一部分。

接下來會從下面四個(gè)方面進(jìn)行逐步分析秆撮,盡量多點(diǎn)干貨四濒。

目錄

  • 現(xiàn)狀分析
  • 治理方案
  • 框架構(gòu)建
  • 總結(jié)

一、現(xiàn)狀分析

前言部分基本闡述了當(dāng)下為什么要構(gòu)建WebView框架,就目前來看峻黍,每個(gè)項(xiàng)目應(yīng)該都是前端和客戶端混合開發(fā)复隆,純原生的項(xiàng)目已經(jīng)退出歷史了。就項(xiàng)目來看姆涩,h5構(gòu)建在客戶端內(nèi)自然少不了要與客戶端打交道挽拂。相信很多App還停留在使用原始攔截的方式進(jìn)行JS和Native端的交互,通過定義好的某個(gè)協(xié)議進(jìn)行攔截JS請求骨饿。這樣的方式雖然簡單亏栈,但缺點(diǎn)太多。

首先從技術(shù)層面來看宏赘,這樣需要做隊(duì)列控制連續(xù)的JS調(diào)用绒北,防止通信丟失,這也是一個(gè)復(fù)雜的工作察署,而且效率低闷游,其次通過假請求攔截,一旦請求參數(shù)拼接過于復(fù)雜還會產(chǎn)生一些其他的副作用贴汪,例如url過長參數(shù)無法被攔截脐往,參數(shù)拼接后字符串截取出錯等等。

備注一下:url攔截處理參數(shù)并非都是使用的這種方式扳埂,例如大名鼎鼎的《Cordova》《WebViewJavaScriptBridge》都是使用的另外一種方式:曲線救國业簿,增加一層JS側(cè)來處理參數(shù)調(diào)度問題,而非直接攔截參數(shù)阳懂。

其次我們從業(yè)務(wù)的層面考慮梅尤,當(dāng)需要通信的需求越來越多,WebView框架內(nèi)的代碼是否也會變得越來越冗余岩调,摻雜的業(yè)務(wù)是否會變得越來越多巷燥,耦合是否越來越高等等。當(dāng)我們有新的需求進(jìn)來了是否要繼續(xù)讓WebView框架變得冗余号枕?復(fù)用就更不可能了矾湃。

相信現(xiàn)在很多App在這一塊還停留在上面的例子中,那么怎么解決這些問題堕澄?首先我們應(yīng)該要有個(gè)好的通信方案邀跃,一個(gè)前衛(wèi)的,先進(jìn)的通信方案可以比作框架的心臟蛙紫。

下面我們繼續(xù)分析一下現(xiàn)在有什么通信方案更適合我們拍屑。

二、治理方案

治理方案這一塊可以看下我的另一篇文章《寫一個(gè)易于維護(hù)使用方便性能可靠的Hybrid框架(一)—— 思路構(gòu)建》坑傅,主要講了框架的構(gòu)建思路僵驰,后兩篇是對思路進(jìn)行了延伸和進(jìn)一步的優(yōu)化。

目前看來在通信選擇這一塊有很多,簡單闡明一下優(yōu)缺點(diǎn):

JS調(diào)用客戶端:

  • 1.假跳轉(zhuǎn)攔截:也就是上面提到的蒜茴,這應(yīng)該是第一個(gè)被pass掉的方案星爪,因?yàn)樗话踩【湍壳爸髁鞯拈_源來看粉私,不論是大名鼎鼎的《Cordova》還是《WebViewJavaScriptBridge》都對它做了大量的操作顽腾,大量的操作,關(guān)于Cordova的操作可以參考我之前的文章《Cordova框架的“曲線救國”》
  • 2.彈窗攔截:UIWebView不支持使用彈窗攔截JS诺核。WKWebView支持confirm()/prompt()彈窗攔截抄肖,同步返回。
  • 3.JavaScriptCore框架注入:這是一個(gè)異常強(qiáng)大的框架窖杀,iOS7開始支持漓摩,強(qiáng)大到RN都是依托于此,充滿了很多黑魔法入客。具體它的使用可以參考《深入淺出 JavaScriptCore》管毙,但是遺憾的是只有UIWebView支持它。WKWebView無法通過kvc獲取JSContext桌硫,所以WK并不支持夭咬。
  • 4.Messagehandler注入:addScriptMessageHandler:函數(shù)誕生于iOS8,伴隨著WKWebView開放給開發(fā)者的鞍泉,所以遺憾的是它只有WKWebView支持,但我把它理解為蘋果通信這一塊的親兒子肮帐,畢竟蘋果爸爸出品咖驮。

上面列出了所有的JS打到Native端的通信途徑,如果我們必須要選擇一個(gè)方案來實(shí)施训枢,優(yōu)先選擇下面兩種:

  • WKWebView首選Messagehandler注入:
[webView.configuration.userContentController addScriptMessageHandler:self name:@"WKJSBridge"];
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message {
    if ([message.body isKindOfClass:[NSArray class]]) {
        [_webViewhandleFactory handleMsgCommand:message.body];
    }
}

JS側(cè)的調(diào)用也會非常簡單托修,通過客戶端注入的WKJSBridge就可以構(gòu)建通信了:

window.webkit.messageHandlers.WKJSBridge.postMessage()

上面的代碼就是Messagehandler方式的通信過程了,很簡單恒界,從代碼中可以很清楚的看到什么是親兒子的通信睦刃,再對比下曲線救國式的通信,對比就灰常明顯了十酣。WKJSBridge就是WKWebView注入的JS函數(shù)涩拙。實(shí)際上客戶端就做了這么點(diǎn)工作就可以了,message.body可以是任意id類型對象耸采,取決于JS端給客戶端傳遞的是什么類型兴泥,demo中傳遞的是NSArray類型。

  • UIWebView首選JavaScriptCore框架:

原因JavaScriptCore功能異常強(qiáng)大虾宇,可以直接給JS注入一個(gè)函數(shù)讓它調(diào)用搓彻,也可以直接給JS注入一個(gè)OC對象讓JS使用,充滿黑科技。不論是RN旭贬,還是Weex怔接,都是基于此來構(gòu)建的通信。具體使用可以通過《WKJavaScriptBridge》深入探究一下稀轨。

客戶端主動調(diào)用JS:

  • 1.evaluatingJavaScript:函數(shù) :只支持UIWebView扼脐,同步回調(diào)。
  • 2.evaluateJavaScript:completionHandler:函數(shù) :只支持WKWebView靶端,異步回調(diào)谎势。

關(guān)于客戶端回調(diào)JS方式毋庸置疑,各自選各自的就可以了杨名。

通信的選擇這塊就確定了:

  • WKWebView:Messagehandler注入和evaluateJavaScript:completionHandler:回調(diào)脏榆。
  • UIWebView:JavaScriptCore框架注入evaluatingJavaScript:回調(diào)。

那么接下來看一下對于業(yè)務(wù)過多導(dǎo)致冗余該怎么處理台谍。

這一塊前面的文章也有提到须喂,可以看看《寫一個(gè)易于維護(hù)使用方便性能可靠的Hybrid框架(二)—— 插件化》了解一下。插件化構(gòu)建趁蕊,讓每一個(gè)業(yè)務(wù)功能都成為一個(gè)module坞生,一個(gè)插件。插件是什么意思掷伙,就是獨(dú)立J羌骸!與除了我們Web框架以外其他的類無任何耦合任柜,它只是被框架管理著卒废,靜靜的在那里工作,刪除了項(xiàng)目依舊BuildV娴亍摔认!插件制作完畢拖到項(xiàng)目可以直接使用。這樣就讓業(yè)務(wù)模塊完全分離宅粥,全部剝離框架参袱,新的需求只需要建立新的模塊即可,不需要動Web框架秽梅。

image

截圖中的Fetch可以理解為JS的請求要客戶端來做這種功能抹蚀,Device可以理解為JS想要客戶端的設(shè)備信息功能等等等...那么有新需求無限擴(kuò)充這種模塊就好了。清晰一目了然企垦。細(xì)節(jié)請下載項(xiàng)目進(jìn)行查看况鸣。關(guān)于插件注冊看一下我前面的文章配置插件。經(jīng)過這樣的處理竹观,是不是我們的代碼就一目了然了镐捧,易維護(hù)潜索,可拓展,重點(diǎn)是無耦合6础竹习!

到這里上面提到的問題就都得到解決了,基于前面的幾篇文章Coding了一個(gè)Hybrid框架《WKJavaScriptBridge》列牺,目前正在往項(xiàng)目中推廣整陌,大家覺得有幫助歡迎Star,有問題歡迎Issue瞎领。關(guān)于WKWebView的各種坑可以看一下WKWebView這篇文章泌辫。下面說一下WKJavaScriptBridge項(xiàng)目的主要構(gòu)建思路。

三九默、框架構(gòu)建

框架地址:https://github.com/GitWangKai/WKJavaScriptBridge

框架結(jié)構(gòu):

image

框架的主要特點(diǎn):兼容了UIWebView&WKWebView震放,插件化了交互業(yè)務(wù)模塊,當(dāng)然還有一些其他特性參照《README.md》驼修。

構(gòu)建原則:解耦殿遂,業(yè)務(wù)分離,低代碼浸入乙各,高可拓展墨礁,高復(fù)用,易集成耳峦。

框架類圖:

image

UIWebView和WKWebView兼容恩静,由業(yè)務(wù)自定義即可,框架不關(guān)心傳入的是那種類型蹲坷,皆可處理驶乾。

項(xiàng)目構(gòu)建主要基于上面提到的痛點(diǎn)問題進(jìn)行了處理,目前為0.0.1版本冠句,后續(xù)會繼續(xù)擴(kuò)充轻掩。具體實(shí)現(xiàn)參照源碼幸乒,如果覺得有幫助懦底,歡迎Star。

四罕扎、總結(jié)

文末做個(gè)總結(jié)聚唐,目前上面的方案只是為我們項(xiàng)目Hybrid打了個(gè)基石,后續(xù)還會有很多很多工作需要延伸腔召。至少目前Hybrid在WebView處理這一塊的組件已經(jīng)出爐了杆查。后續(xù)會基于此,擴(kuò)充離線包臀蛛、JS側(cè)插件化處理亲桦、引入Flutter跨端技術(shù)崖蜜、構(gòu)建小程序框架。接下來我會構(gòu)建第二個(gè)功能:離線包組件客峭。

敬請期待豫领。

如果由任何疑問或者建議歡迎issue,讓它變得更好舔琅。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末等恐,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子备蚓,更是在濱河造成了極大的恐慌课蔬,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,542評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件郊尝,死亡現(xiàn)場離奇詭異二跋,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)虚循,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,822評論 3 394
  • 文/潘曉璐 我一進(jìn)店門同欠,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人横缔,你說我怎么就攤上這事铺遂。” “怎么了茎刚?”我有些...
    開封第一講書人閱讀 163,912評論 0 354
  • 文/不壞的土叔 我叫張陵襟锐,是天一觀的道長。 經(jīng)常有香客問我膛锭,道長粮坞,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,449評論 1 293
  • 正文 為了忘掉前任初狰,我火速辦了婚禮莫杈,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘奢入。我一直安慰自己筝闹,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,500評論 6 392
  • 文/花漫 我一把揭開白布腥光。 她就那樣靜靜地躺著关顷,像睡著了一般。 火紅的嫁衣襯著肌膚如雪武福。 梳的紋絲不亂的頭發(fā)上议双,一...
    開封第一講書人閱讀 51,370評論 1 302
  • 那天,我揣著相機(jī)與錄音捉片,去河邊找鬼平痰。 笑死汞舱,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的宗雇。 我是一名探鬼主播兵拢,決...
    沈念sama閱讀 40,193評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼逾礁!你這毒婦竟也來了说铃?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,074評論 0 276
  • 序言:老撾萬榮一對情侶失蹤嘹履,失蹤者是張志新(化名)和其女友劉穎腻扇,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體砾嫉,經(jīng)...
    沈念sama閱讀 45,505評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡幼苛,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,722評論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了焕刮。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片舶沿。...
    茶點(diǎn)故事閱讀 39,841評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖配并,靈堂內(nèi)的尸體忽然破棺而出括荡,到底是詐尸還是另有隱情,我是刑警寧澤溉旋,帶...
    沈念sama閱讀 35,569評論 5 345
  • 正文 年R本政府宣布畸冲,位于F島的核電站,受9級特大地震影響观腊,放射性物質(zhì)發(fā)生泄漏邑闲。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,168評論 3 328
  • 文/蒙蒙 一梧油、第九天 我趴在偏房一處隱蔽的房頂上張望苫耸。 院中可真熱鬧,春花似錦儡陨、人聲如沸褪子。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,783評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽褐筛。三九已至类少,卻和暖如春叙身,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背硫狞。 一陣腳步聲響...
    開封第一講書人閱讀 32,918評論 1 269
  • 我被黑心中介騙來泰國打工信轿, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留晃痴,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,962評論 2 370
  • 正文 我出身青樓财忽,卻偏偏與公主長得像倘核,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子即彪,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,781評論 2 354