原文地址:iOS 應(yīng)用架構(gòu)談 動(dòng)態(tài)部署方案
前言
這里討論的動(dòng)態(tài)部署方案厌秒,就是指通過(guò)不發(fā)版的方式儒喊,將新的內(nèi)容供汛、新的業(yè)務(wù)流程部署進(jìn)已發(fā)布的App痢缎。因?yàn)樘O(píng)果的審核周期比較長(zhǎng)胁勺,而且蘋(píng)果的限制比較多,業(yè)界在這里也沒(méi)有特別多的手段來(lái)達(dá)到動(dòng)態(tài)部署方案的目的独旷。這篇文章主要的目的就是給大家列舉一下目前業(yè)界做動(dòng)態(tài)部署的手段署穗,以及其對(duì)應(yīng)的優(yōu)缺點(diǎn)寥裂。然后給出一套我比較傾向于使用的方案。
其實(shí)單純就動(dòng)態(tài)部署方案來(lái)講蛇捌,沒(méi)什么太多花頭可以說(shuō)的抚恒,就是H5、Lua络拌、JS、OC/Swift這幾門(mén)基本技術(shù)的各種組合排列回溺。寫(xiě)到后面覺(jué)得春贸,動(dòng)態(tài)部署方案其實(shí)是非常好的用于講解某些架構(gòu)模式的背景。一般我們經(jīng)驗(yàn)總結(jié)下來(lái)的架構(gòu)模式包括但不限于:
- Layered Architecture
- Event-Driven Architecture
- Microkernel Architecture
- Microservices Architecture
- Space-Based Architecture
我在開(kāi)篇里面提到的MVC等方案跟這篇文章中要提到的架構(gòu)模式并不是屬于同一個(gè)維度的遗遵。比較容易混淆的就是容易把MVC這些方案跟Layered Architecture混淆萍恕,這個(gè)我在開(kāi)篇這篇文章里面也做過(guò)了區(qū)分:MVC等方案比較側(cè)重于數(shù)據(jù)流動(dòng)方向的控制和數(shù)據(jù)流的管理。Layered Architecture更加側(cè)重于各分層之間的功能劃分和模塊協(xié)作车要。
另外允粤,上述五種架構(gòu)模式在Software Architecture Patterns這本書(shū)里有非常詳細(xì)的介紹,整本書(shū)才45頁(yè)翼岁,個(gè)把小時(shí)就看完了类垫,非常值得看和思考。本文后半篇涉及的架構(gòu)模式是以上架構(gòu)模式的其中兩種:Microkernel Architecture和Microservices Architecture琅坡。
最后悉患,文末還給出了其他一些關(guān)于架構(gòu)模式的我覺(jué)得還不錯(cuò)的PPT和論文,里面對(duì)架構(gòu)模式的分類(lèi)和總結(jié)也比較多樣榆俺,跟Software Architecture Patterns的總結(jié)也有些許不一樣的地方售躁,可以博采眾長(zhǎng)。
Web App
實(shí)現(xiàn)方案
其實(shí)所謂的web app茴晋,就是通過(guò)手機(jī)上的瀏覽器進(jìn)行訪(fǎng)問(wèn)的H5頁(yè)面陪捷。這個(gè)H5頁(yè)面是針對(duì)移動(dòng)場(chǎng)景特別優(yōu)化的,比如UI交互等诺擅。
優(yōu)點(diǎn)
無(wú)需走蘋(píng)果流程市袖,所有蘋(píng)果流程帶來(lái)的成本都能避免,包括審核周期掀虎、證書(shū)成本等凌盯。
版本更新跟網(wǎng)頁(yè)一樣,隨時(shí)生效烹玉。
不需要Native App工程師的參與驰怎,而且市面上已經(jīng)有很多針對(duì)這種場(chǎng)景的框架。
缺點(diǎn)
由于每一頁(yè)都需要從服務(wù)器下載二打,因此web app重度依賴(lài)網(wǎng)絡(luò)環(huán)境县忌。
同樣的UI效果使用web app來(lái)實(shí)現(xiàn)的話(huà),流暢度不如Native,比較影響用戶(hù)體驗(yàn)症杏。
本地持久化的部分很難做好装获,繞過(guò)本地持久化的部分的辦法就是提供賬戶(hù)體系,對(duì)應(yīng)賬戶(hù)的持久化數(shù)據(jù)全部存在服務(wù)端厉颤。
即時(shí)響應(yīng)方案穴豫、遠(yuǎn)程通知實(shí)現(xiàn)方案、移動(dòng)端傳感器的使用方案復(fù)雜逼友,維護(hù)難度大精肃。
安全問(wèn)題帜乞,H5頁(yè)面等于是所有東西都暴露給了用戶(hù)司抱,如果對(duì)安全要求比較高的,很多額外的安全機(jī)制都需要在服務(wù)端實(shí)現(xiàn)黎烈。
總結(jié)
web app一般是創(chuàng)業(yè)初期會(huì)重點(diǎn)考慮的方案习柠,因?yàn)榈浅?煺掌澹覄?chuàng)業(yè)初期的主要目標(biāo)是需要驗(yàn)證模式的正確性资溃,并不在于提供非常好的用戶(hù)體驗(yàn),只需要完成閉環(huán)即可必怜。早年facebook曾經(jīng)嘗試過(guò)這種方案肉拓,最后因?yàn)橛脩?hù)體驗(yàn)的問(wèn)題而宣布放棄。所以這個(gè)方案只能作為過(guò)渡方案梳庆,或者當(dāng)App不可用時(shí)暖途,作為降級(jí)方案使用。
Hybrid App
通過(guò)市面上各種Hybrid框架膏执,來(lái)做H5和Native的混合應(yīng)用驻售,或者通過(guò)JS Bridge來(lái)做到H5和Native之間的數(shù)據(jù)互通。
優(yōu)點(diǎn)
除了要承擔(dān)蘋(píng)果流程導(dǎo)致的成本以外更米,具備所有web app的優(yōu)勢(shì)
能夠訪(fǎng)問(wèn)本地?cái)?shù)據(jù)欺栗、設(shè)備傳感器等
缺點(diǎn)
跟web app一樣存在過(guò)度依賴(lài)網(wǎng)絡(luò)環(huán)境的問(wèn)題
用戶(hù)體驗(yàn)也很難做到很好
安全性問(wèn)題依舊存在
大規(guī)模的數(shù)據(jù)交互很難實(shí)現(xiàn),例如圖片在本地處理后征峦,將圖片傳遞給H5
總結(jié)
Hybrid方案更加適合跟本地資源交互不是很多迟几,然后主要以?xún)?nèi)容展示為主的App。在天貓App中栏笆,大量地采用了JS Bridge的方式來(lái)讓H5跟Native做交互类腮,因?yàn)樘熵圓pp是一個(gè)以?xún)?nèi)容展示為主的App,且營(yíng)銷(xiāo)活動(dòng)多蛉加,周期短蚜枢,比較適合Hybrid缸逃。
React-Native
嚴(yán)格來(lái)說(shuō),React-Native應(yīng)當(dāng)放到Hybrid那一節(jié)去講厂抽,單獨(dú)拎出來(lái)的原因是Facebook自從放出React-Native之后需频,業(yè)界討論得非常激烈。天貓的鬼道也做了非常多的關(guān)于React-Native的分享筷凤。
React-Native這個(gè)框架比較特殊昭殉,它展示View的方式依然是Native的View,然后也是可以通過(guò)URL的方式來(lái)動(dòng)態(tài)生成View嵌施。而且饲化,React-Native也提供了一個(gè)Bridge通道來(lái)做Javascript和Objective-C之間的交流,還是很貼心的吗伤。
然而研究了一下發(fā)現(xiàn)有一個(gè)比較坑的地方在于,解析JS要生成View時(shí)所需要的View硫眨,是要本地能夠提供的足淆。舉個(gè)例子,比如你要有一個(gè)特定的Mapview礁阁,并且要響應(yīng)對(duì)應(yīng)的delegate方法巧号,在React-Native的環(huán)境下,你需要先在Native提供這個(gè)Mapview姥闭,并且自己實(shí)現(xiàn)這些delegate方法丹鸿,在實(shí)現(xiàn)完方法之后通過(guò)Bridge把數(shù)據(jù)回傳給JS端,然后重新渲染棚品。
在這種情況下我們就能發(fā)現(xiàn)靠欢,其實(shí)React-Native在使用View的時(shí)候,這些View是要經(jīng)過(guò)本地定制的铜跑,并且將相關(guān)方法通過(guò)RCT_EXPORT_METHOD暴露給js门怪,js端才能正常使用。在我看來(lái)锅纺,這里在一定程度上限制了動(dòng)態(tài)部署時(shí)的靈活性掷空,比如我們需要在某個(gè)點(diǎn)擊事件中展示一個(gè)動(dòng)畫(huà)或者一個(gè)全新的view,由于本地沒(méi)有實(shí)現(xiàn)這個(gè)事件或沒(méi)有這個(gè)view囤锉,React-Native就顯得捉襟見(jiàn)肘坦弟。
優(yōu)點(diǎn)
響應(yīng)速度很快,只比Native慢一點(diǎn)官地,比webview快很多酿傍。
能夠做到一定程度上的動(dòng)態(tài)部署
缺點(diǎn)
組裝頁(yè)面的元素需要Native提供支持,一定程度上限制了動(dòng)態(tài)部署的靈活性区丑。
總結(jié)
由于React-Native框架中拧粪,因?yàn)閂iew的展示和View的事件響應(yīng)分屬于不同的端修陡,展示部分的描述在JS端,響應(yīng)事件的監(jiān)聽(tīng)和描述都在Native端可霎,通過(guò)Native轉(zhuǎn)發(fā)給JS端魄鸦。所以,從做動(dòng)態(tài)部署的角度上講癣朗,React-Native只能動(dòng)態(tài)部署新View拾因,不能動(dòng)態(tài)部署新View對(duì)應(yīng)的事件。當(dāng)然旷余,React-Native本身提供了很多基礎(chǔ)組件绢记,然而這個(gè)問(wèn)題仍然還是會(huì)限制動(dòng)態(tài)部署的靈活性。因?yàn)槲覀冊(cè)趧?dòng)態(tài)部署的時(shí)候正卧,大部分情況下是希望View和事件響應(yīng)一起改變的蠢熄。
另外一個(gè)問(wèn)題就在于,View的原型需要從Native中取炉旷,這個(gè)問(wèn)題相較于上面一個(gè)問(wèn)題倒是顯得不那么嚴(yán)重签孔,只是以后某個(gè)頁(yè)面需要添加某個(gè)復(fù)雜的view的時(shí)候,需要從現(xiàn)有的組件中拼裝罷了窘行。
所以饥追,React-Native事實(shí)上解決的是如何不使用Objc/Swift來(lái)寫(xiě)iOS App的View的問(wèn)題,對(duì)于如何通過(guò)不發(fā)版來(lái)給已發(fā)版的App更新功能這樣的問(wèn)題罐盔,幫助有限但绕。
Lua Patch
大眾點(diǎn)評(píng)的屠毅敏同學(xué)在基于wax的基礎(chǔ)上寫(xiě)了waxPatch,這個(gè)工具的主要原理是通過(guò)lua來(lái)針對(duì)objc的方法進(jìn)行替換惶看,由于lua本身是解釋型語(yǔ)言捏顺,可以通過(guò)動(dòng)態(tài)下載得到,因此具備了一定的動(dòng)態(tài)部署能力碳竟。然而iOS系統(tǒng)原生并不提供lua的解釋庫(kù)草丧,所以需要在打包時(shí)把lua的解釋庫(kù)編譯進(jìn)app。
優(yōu)點(diǎn)
能夠通過(guò)下載腳本替換方法的方式莹桅,修改本地App的行為昌执。
執(zhí)行效率較高
缺點(diǎn)
對(duì)于替換功能來(lái)說(shuō),lua是很不錯(cuò)的選擇诈泼。但如果要添加新內(nèi)容懂拾,實(shí)際操作會(huì)很復(fù)雜
很容易改錯(cuò),小問(wèn)題變成大問(wèn)題
總結(jié)
lua的解決方案在一定程度上解決了動(dòng)態(tài)部署的問(wèn)題铐达。實(shí)際操作時(shí)岖赋,一般不使用它來(lái)做新功能的動(dòng)態(tài)部署,主要還是用于修復(fù)bug時(shí)代碼的動(dòng)態(tài)部署瓮孙。實(shí)際操作時(shí)需要注意的另外一點(diǎn)是唐断,真的很容易改錯(cuò)选脊,尤其是你那個(gè)方法特別長(zhǎng)的時(shí)候,所以改了之后要徹底回歸測(cè)試一次脸甘。
Javascript Patch
這個(gè)工作原理其實(shí)跟上面說(shuō)的lua那套方案的工作原理一樣恳啥,只不過(guò)是用javascript實(shí)現(xiàn)。而且最近新出了一個(gè)JSPatch這個(gè)庫(kù)丹诀,相當(dāng)好用钝的。
優(yōu)點(diǎn)
同Lua方案的優(yōu)點(diǎn)
打包時(shí)不用將解釋器也編譯進(jìn)去,iOS自帶JavaScript的解釋器铆遭,只不過(guò)要從iOS7.0以后才支持硝桩。
缺點(diǎn)
同Lua方案的缺點(diǎn)
總結(jié)
在對(duì)app打補(bǔ)丁的方案中,目前我更傾向于使用JSPatch的方案枚荣,在能夠完成Lua做到的所有事情的同時(shí)碗脊,還不用編一個(gè)JS解釋器進(jìn)去,而且會(huì)javascript的人比會(huì)lua的人多橄妆,技術(shù)儲(chǔ)備比較好做望薄。
JSON Descripted View
其實(shí)這個(gè)方案的原理是這樣的:使用JSON來(lái)描述一個(gè)View應(yīng)該有哪些元素,以及元素的位置呼畸,以及相關(guān)的屬性,比如背景色颁虐,圓角等等蛮原。然后本地有一個(gè)解釋器來(lái)把JSON描述的View生成出來(lái)。
這跟React-Native有點(diǎn)兒像另绩,一個(gè)是JS轉(zhuǎn)Native儒陨,一個(gè)是JSON轉(zhuǎn)Native。但是同樣有的問(wèn)題就是事件處理的問(wèn)題笋籽,在事件處理上蹦漠,React-Native做得相對(duì)更好。因?yàn)镴SON不能夠描述事件邏輯车海,所以JSON生成的View所需要的事件處理都必須要本地事先掛好笛园。
優(yōu)點(diǎn)
能夠自由生成View并動(dòng)態(tài)部署
缺點(diǎn)
天貓實(shí)際使用下來(lái),發(fā)現(xiàn)還是存在一定的性能問(wèn)題侍芝,不夠快
事件需要本地事先寫(xiě)好研铆,無(wú)法動(dòng)態(tài)部署事件
總結(jié)
其實(shí)JSON描述的View比React-Native的View有個(gè)好處就在于對(duì)于這個(gè)View而言,不需要本地也有一套對(duì)應(yīng)的View州叠,它可以依據(jù)JSON的描述來(lái)自己生成棵红。然而對(duì)于事件的處理是它的硬傷,所以JSON描述View的方案咧栗,一般比較適用于換膚逆甜,或者固定事件不同樣式的View虱肄,比如貼紙。
架構(gòu)模式
其實(shí)我們要做到動(dòng)態(tài)部署交煞,至少要滿(mǎn)足以下需求:
- View和事件都要能夠動(dòng)態(tài)部署
- 功能完整
- 便于維護(hù)
我更加傾向于H5和Native以JSBridge的方式連接的方案進(jìn)行動(dòng)態(tài)部署咏窿,在cocoapods里面也有蠻多的JSBridge了〈砀遥看了一圈之后翰灾,我還是選擇寫(xiě)了一個(gè)CTJSBridge,來(lái)滿(mǎn)足動(dòng)態(tài)部署和后續(xù)維護(hù)的需求稚茅。關(guān)于這個(gè)JSBridge的使用中的任何問(wèn)題和需求纸淮,都可以在評(píng)論區(qū)向我提出來(lái)。接下來(lái)的內(nèi)容亚享,會(huì)主要討論以下這些問(wèn)題:
1.為什么不是React-Native或其它方案咽块?
2.采用什么樣的架構(gòu)模式才是使用JSBridge的最佳實(shí)踐?
為什么不是React-Native或其他方案欺税?
首先針對(duì)React-Native來(lái)做解釋?zhuān)懊嬉呀?jīng)分析到侈沪,React-Native有一個(gè)比較大的局限在于View需要本地提供。假設(shè)有一個(gè)頁(yè)面的組件是跑馬燈晚凿,如果本地沒(méi)有對(duì)應(yīng)的View亭罪,使用React-Native就顯得很麻煩。然而同樣的情況下歼秽,HTML5能夠很好地實(shí)現(xiàn)這樣的需求应役。這里存在一個(gè)這樣的取舍在性能和動(dòng)態(tài)部署View及事件之間,選擇哪一個(gè)燥筷?
我更加傾向于能夠動(dòng)態(tài)部署View和事件箩祥,至少后者是能夠完成需求的,性能再好肆氓,難以完成需求其實(shí)沒(méi)什么意義袍祖。然而對(duì)于HTML5的Hybrid和純HTML5的web app之間,也存在一個(gè)相同的取舍谢揪,但是還要額外考慮一個(gè)新的問(wèn)題蕉陋,純HTML5能夠使用到的設(shè)備提供的功能相對(duì)有限,JSBridge能夠?qū)⒉糠衷O(shè)備的功能以Native API的方式交付給頁(yè)面键耕,因此在考慮這個(gè)問(wèn)題之后寺滚,選擇HTML5的Hybrid方案就顯得理所應(yīng)當(dāng)了。
在諸多Hybrid方案中屈雄,除了JSBridge之外村视,其它的方案都顯得相對(duì)過(guò)于沉重,對(duì)于動(dòng)態(tài)部署來(lái)說(shuō)酒奶,其實(shí)需要補(bǔ)充的軟肋就是提供本地設(shè)備的功能蚁孔,其它的反而顯得較為累贅奶赔。
基于JSBridge的微服務(wù)架構(gòu)模式
-------------------------
| |
| HTML5 |
| |
| View + Event Response |
| |
-------------------------
|
|
|
JSBridge
|
|
|
------------------------------------------------------------------------------
| |
| Native |
| |
| ------------ ------------ ------------ ------------ ------------ |
| | | | | | | | | | | |
| | Service1 | | Service2 | | Service3 | | Service4 | | ... | |
| | | | | | | | | | | |
| ------------ ------------ ------------ ------------ ------------ |
| |
| |
------------------------------------------------------------------------------
解釋一下這種架構(gòu)背后的思想:
因?yàn)镠5和Native之間能夠通過(guò)JSBridge進(jìn)行交互,然而JSBridge的一個(gè)特征是杠氢,只能H5主動(dòng)發(fā)起調(diào)用站刑。所以理所應(yīng)當(dāng)?shù)兀徽{(diào)用者為調(diào)用者提供服務(wù)鼻百。
另外一個(gè)想要處理的問(wèn)題是绞旅,希望能夠通過(guò)微服務(wù)架構(gòu),來(lái)把H5和Native各自的問(wèn)題域區(qū)分開(kāi)温艇。所謂區(qū)分問(wèn)題域就是讓H5要解決的問(wèn)題和Native要解決的問(wèn)題之間因悲,交集最小。因此勺爱,我們?cè)O(shè)計(jì)時(shí)希望H5的問(wèn)題域能夠更加偏重業(yè)務(wù)晃琳,然后Native為H5的業(yè)務(wù)提供基礎(chǔ)功能支持,例如API的跨域調(diào)用琐鲁,傳感器設(shè)備信息以及本地已經(jīng)沉淀的業(yè)務(wù)模塊都可以作為Native提供的服務(wù)交給H5去使用卫旱。H5的快速部署特性特別適合做重業(yè)務(wù)的事情,Native對(duì)iPhone的功能調(diào)用能力和控制能力特別適合將其封裝成服務(wù)交給H5調(diào)用围段。
所以這對(duì)Native提供的服務(wù)有兩點(diǎn)要求:
- Native提供的服務(wù)不應(yīng)當(dāng)是強(qiáng)業(yè)務(wù)相關(guān)的顾翼,最好是跟業(yè)務(wù)無(wú)關(guān),這樣才能方便H5進(jìn)行業(yè)務(wù)的組裝
2.如果Native一定要提供強(qiáng)業(yè)務(wù)相關(guān)的服務(wù)奈泪,那最好是一個(gè)完整業(yè)務(wù)暴构,這樣H5就能比較方便地調(diào)用業(yè)務(wù)模塊。
只要Native提供的服務(wù)符合上述兩個(gè)條件段磨,HTML5在實(shí)現(xiàn)業(yè)務(wù)的時(shí)候,束縛就會(huì)非常少耗绿,也非常容易管理苹支。
然后這種方案也會(huì)有一定的局限性,就是如果Native沒(méi)有提供這樣的服務(wù)误阻,那還是必須得靠發(fā)版來(lái)解決债蜜。等于就是Native向HTML5提供API,這其實(shí)跟服務(wù)端向Native提供API的道理一樣究反。
但基于Native提供的服務(wù)的通用性這點(diǎn)來(lái)看寻定,添加服務(wù)的需求不會(huì)特別頻繁,每一個(gè)App都有屬于自己的業(yè)務(wù)領(lǐng)域精耐,在同一個(gè)業(yè)務(wù)領(lǐng)域下狼速,其實(shí)需要Native提供的服務(wù)是有限的。然后結(jié)合JSPatch提供的動(dòng)態(tài)patch的能力卦停,這樣的架構(gòu)能夠滿(mǎn)足絕大部分動(dòng)態(tài)部署的需求向胡。
然后隨著App的不斷迭代恼蓬,某些HTML5的實(shí)現(xiàn)其實(shí)是可以逐步沉淀為Native實(shí)現(xiàn)的,這在一定程度上僵芹,降低了App早期的試錯(cuò)成本处硬。
基于動(dòng)態(tài)庫(kù)的微內(nèi)核模式
我開(kāi)發(fā)了CTDynamicLibKit這個(gè)庫(kù)來(lái)解決動(dòng)態(tài)庫(kù)的調(diào)用問(wèn)題,其實(shí)原先的打算是拿動(dòng)態(tài)庫(kù)做動(dòng)態(tài)部署的拇派,不過(guò)我用@念紀(jì) 的個(gè)人App把這個(gè)功能塞進(jìn)去之后荷辕,發(fā)現(xiàn)蘋(píng)果還是能審核通過(guò)的,但是下載下來(lái)的動(dòng)態(tài)庫(kù)是無(wú)法加載的件豌。報(bào)錯(cuò)如下:
error:Error Domain=NSCocoaErrorDomain Code=3587 "The bundle “DynamicLibDemo” couldn’t be loaded because it is damaged or missing necessary resources." (dlopen_preflight(/var/mobile/Containers/Data/Application/61D3BF00-CF8D-4157-A87C-D999905E9040/Library/DynamicLibDemo1.framework/DynamicLibDemo): no suitable image found. Did find:
/var/mobile/Containers/Data/Application/61D3BF00-CF8D-4157-A87C-D999905E9040/Library/DynamicLibDemo1.framework/DynamicLibDemo: code signature invalid for '/var/mobile/Containers/Data/Application/61D3BF00-CF8D-4157-A87C-D999905E9040/Library/DynamicLibDemo1.framework/DynamicLibDemo'
) UserInfo=0x174260b80 {NSLocalizedFailureReason=The bundle is damaged or missing necessary resources., NSLocalizedRecoverySuggestion=Try reinstalling the bundle., NSFilePath=/var/mobile/Containers/Data/Application/61D3BF00-CF8D-4157-A87C-D999905E9040/Library/DynamicLibDemo1.framework/DynamicLibDemo, NSDebugDescription=dlopen_preflight(/var/mobile/Containers/Data/Application/61D3BF00-CF8D-4157-A87C-D999905E9040/Library/DynamicLibDemo1.framework/DynamicLibDemo): no suitable image found. Did find:
/var/mobile/Containers/Data/Application/61D3BF00-CF8D-4157-A87C-D999905E9040/Library/DynamicLibDemo1.framework/DynamicLibDemo: code signature invalid for '/var/mobile/Containers/Data/Application/61D3BF00-CF8D-4157-A87C-D999905E9040/Library/DynamicLibDemo1.framework/DynamicLibDemo'
, NSBundlePath=/var/mobile/Containers/Data/Application/61D3BF00-CF8D-4157-A87C-D999905E9040/Library/DynamicLibDemo1.framework, NSLocalizedDescription=The bundle “DynamicLibDemo” couldn’t be loaded because it is damaged or missing necessary resources.}
主要原因是因?yàn)楹灻麩o(wú)法通過(guò)疮方。因?yàn)镈istribution的App只能加載相同證書(shū)打包的framework。在in house和develop模式下苟径,可以使用相同證書(shū)既打包App又打包framework案站,所以測(cè)試的時(shí)候沒(méi)有問(wèn)題。但是在正式的distribution下棘街,這種做法是行不通的蟆盐。
所以就目前看來(lái),基于動(dòng)態(tài)庫(kù)的動(dòng)態(tài)部署方案是沒(méi)辦法做到的遭殉。
總結(jié)
我在文中針對(duì)業(yè)界常見(jiàn)的動(dòng)態(tài)部署方案做了一些總結(jié)石挂,并且提供了我自己認(rèn)為的最佳解決方案以及對(duì)應(yīng)的JSBridge實(shí)現(xiàn)。文中提到的方案我已經(jīng)盡可能地做到了全面险污,如果還有什么我遺漏沒(méi)寫(xiě)的痹愚,大家可以在評(píng)論區(qū)指出,我把它補(bǔ)上去蛔糯。