(轉(zhuǎn))iOS 應(yīng)用架構(gòu)談 動(dòng)態(tài)部署方案

原文地址: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)模式包括但不限于:

  1. Layered Architecture
  2. Event-Driven Architecture
  3. Microkernel Architecture
  4. Microservices Architecture
  5. 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)足以下需求:

  1. View和事件都要能夠動(dòng)態(tài)部署
  2. 功能完整
  3. 便于維護(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)要求:

  1. 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ǔ)上去蛔糯。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末拯腮,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子蚁飒,更是在濱河造成了極大的恐慌动壤,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,695評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件淮逻,死亡現(xiàn)場(chǎng)離奇詭異琼懊,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)爬早,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,569評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門(mén)哼丈,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人筛严,你說(shuō)我怎么就攤上這事醉旦。” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 168,130評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵髓抑,是天一觀(guān)的道長(zhǎng)咙崎。 經(jīng)常有香客問(wèn)我,道長(zhǎng)吨拍,這世上最難降的妖魔是什么褪猛? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,648評(píng)論 1 297
  • 正文 為了忘掉前任,我火速辦了婚禮羹饰,結(jié)果婚禮上伊滋,老公的妹妹穿的比我還像新娘。我一直安慰自己队秩,他們只是感情好笑旺,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,655評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著馍资,像睡著了一般筒主。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上鸟蟹,一...
    開(kāi)封第一講書(shū)人閱讀 52,268評(píng)論 1 309
  • 那天乌妙,我揣著相機(jī)與錄音,去河邊找鬼建钥。 笑死藤韵,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的熊经。 我是一名探鬼主播泽艘,決...
    沈念sama閱讀 40,835評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼镐依!你這毒婦竟也來(lái)了匹涮?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,740評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤槐壳,失蹤者是張志新(化名)和其女友劉穎焕盟,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體宏粤,經(jīng)...
    沈念sama閱讀 46,286評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,375評(píng)論 3 340
  • 正文 我和宋清朗相戀三年灼卢,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了绍哎。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,505評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡鞋真,死狀恐怖崇堰,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤海诲,帶...
    沈念sama閱讀 36,185評(píng)論 5 350
  • 正文 年R本政府宣布繁莹,位于F島的核電站,受9級(jí)特大地震影響特幔,放射性物質(zhì)發(fā)生泄漏咨演。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,873評(píng)論 3 333
  • 文/蒙蒙 一蚯斯、第九天 我趴在偏房一處隱蔽的房頂上張望薄风。 院中可真熱鬧,春花似錦拍嵌、人聲如沸遭赂。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,357評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)撇他。三九已至,卻和暖如春狈蚤,著一層夾襖步出監(jiān)牢的瞬間困肩,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,466評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工炫惩, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留僻弹,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,921評(píng)論 3 376
  • 正文 我出身青樓他嚷,卻偏偏與公主長(zhǎng)得像蹋绽,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子筋蓖,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,515評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容