一、課題背景
在APP發(fā)布到AppStore之后羡玛,發(fā)現(xiàn)有bug需要修復(fù)别智,按正常的流程是,在修復(fù)bug之后稼稿,重新發(fā)布版本薄榛,等待漫長(zhǎng)的蘋果審核。
二让歼、解決方案
為了頻繁發(fā)布版本敞恋,以及等待蘋果的審核,我們需要使用動(dòng)態(tài)部署來做動(dòng)態(tài)更新谋右,不僅可以修復(fù)在線bug硬猫,還可以按需發(fā)布功能,替換主題等。
(1)做到動(dòng)態(tài)部署啸蜜,至少要滿足以下需求:
???????? 1坑雅、View和事件都要能夠動(dòng)態(tài)部署
???????? 2、功能完整
???????? 3衬横、便于維護(hù)
(2)我們來看看行業(yè)內(nèi)使用的各種動(dòng)態(tài)部署技術(shù)以及優(yōu)缺點(diǎn):
1裹粤、web APP
實(shí)現(xiàn)方案
其實(shí)所謂的web app,就是通過手機(jī)上的瀏覽器進(jìn)行訪問的H5頁面冕香。這個(gè)H5頁面是針對(duì)移動(dòng)場(chǎng)景特別優(yōu)化的蛹尝,比如UI交互等。
優(yōu)點(diǎn)
無需走蘋果流程悉尾,所有蘋果流程帶來的成本都能避免突那,包括審核周期、證書成本等构眯。
版本更新跟網(wǎng)頁一樣愕难,隨時(shí)生效。
不需要Native App工程師的參與惫霸,而且市面上已經(jīng)有很多針對(duì)這種場(chǎng)景的框架猫缭。
缺點(diǎn)
由于每一頁都需要從服務(wù)器下載,因此web app重度依賴網(wǎng)絡(luò)環(huán)境壹店。
同樣的UI效果使用web app來實(shí)現(xiàn)的話猜丹,流暢度不如Native,比較影響用戶體驗(yàn)硅卢。
本地持久化的部分很難做好射窒,繞過本地持久化的部分的辦法就是提供賬戶體系,對(duì)應(yīng)賬戶的持久化數(shù)據(jù)全部存在服務(wù)端将塑。
即時(shí)響應(yīng)方案脉顿、遠(yuǎn)程通知實(shí)現(xiàn)方案、移動(dòng)端傳感器的使用方案復(fù)雜点寥,維護(hù)難度大艾疟。
安全問題,H5頁面等于是所有東西都暴露給了用戶敢辩,如果對(duì)安全要求比較高的蔽莱,很多額外的安全機(jī)制都需要在服務(wù)端實(shí)現(xiàn)。
總結(jié)
web app一般是創(chuàng)業(yè)初期會(huì)重點(diǎn)考慮的方案戚长,因?yàn)榈浅盗冷?欤覄?chuàng)業(yè)初期的主要目標(biāo)是需要驗(yàn)證模式的正確性历葛,并不在于提供非常好的用戶體驗(yàn)正塌,只需要完成閉環(huán) 即可。早年facebook曾經(jīng)嘗試過這種方案恤溶,最后因?yàn)橛脩趔w驗(yàn)的問題而宣布放棄乓诽。所以這個(gè)方案只能作為過渡方案,或者當(dāng)App不可用時(shí)咒程,作為降級(jí)方案 使用鸠天。
2、hybrid APP
通過市面上各種Hybrid框架帐姻,來做H5和Native的混合應(yīng)用稠集,或者通過JS Bridge來做到H5和Native之間的數(shù)據(jù)互通。
優(yōu)點(diǎn)
除了要承擔(dān)蘋果流程導(dǎo)致的成本以外饥瓷,具備所有web app的優(yōu)勢(shì)
能夠訪問本地?cái)?shù)據(jù)剥纷、設(shè)備傳感器等
缺點(diǎn)
跟web app一樣存在過度依賴網(wǎng)絡(luò)環(huán)境的問題
用戶體驗(yàn)也很難做到很好
安全性問題依舊存在
大規(guī)模的數(shù)據(jù)交互很難實(shí)現(xiàn),例如圖片在本地處理后呢铆,將圖片傳遞給H5
總結(jié)
Hybrid方案更加適合跟本地資源交互不是很多晦鞋,然后主要以內(nèi)容展示為主的App。在天貓App中棺克,大量地采用了JS Bridge的方式來讓H5跟Native做交互悠垛,因?yàn)樘熵圓pp是一個(gè)以內(nèi)容展示為主的App,且營(yíng)銷活動(dòng)多娜谊,周期短确买,比較適合Hybrid。
3纱皆、React-Native
React-Native這個(gè)框架比較特殊湾趾,它展示View的方式依然是Native的View,然后也是可以通過URL的方式來動(dòng)態(tài)生成 View抹剩。而且撑帖,React-Native也提供了一個(gè)Bridge通道來做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)完方法之后通過Bridge把數(shù)據(jù)回傳給JS端面氓,然后重新渲染兵钮。
在這種情況下我們就能發(fā)現(xiàn),其實(shí) React-Native在使用View的時(shí)候舌界,這些View是要經(jīng)過本地定制的掘譬,并且將相關(guān)方法通過RCT_EXPORT_METHOD暴露給 js,js端才能正常使用呻拌。在我看來葱轩,這里在一定程度上限制了動(dòng)態(tài)部署時(shí)的靈活性,比如我們需要在某個(gè)點(diǎn)擊事件中展示一個(gè)動(dòng)畫或者一個(gè)全新的view藐握,由 于本地沒有實(shí)現(xiàn)這個(gè)事件或沒有這個(gè)view靴拱,React-Native就顯得捉襟見肘。
優(yōu)點(diǎn)
響應(yīng)速度很快猾普,只比Native慢一點(diǎn)袜炕,比webview快很多。
能夠做到一定程度上的動(dòng)態(tài)部署
缺點(diǎn)
組裝頁面的元素需要Native提供支持初家,一定程度上限制了動(dòng)態(tài)部署的靈活性妇蛀。
總結(jié)
由 于React-Native框架中,因?yàn)閂iew的展示和View的事件響應(yīng)分屬于不同的端笤成,展示部分的描述在JS端评架,響應(yīng)事件的監(jiān)聽和描述都在 Native端,通過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è)問題仍然還是會(huì)限制動(dòng)態(tài)部署的靈活性嗡呼。因?yàn)槲覀冊(cè)趧?dòng)態(tài)部署的時(shí)候, 大部分情況下是希望View和事件響應(yīng)一起改變的皇耗。
另外一個(gè)問題就在于南窗,View的原型需要從Native中取,這個(gè)問題相較于上面一個(gè)問題倒是顯得不那么嚴(yán)重郎楼,只是以后某個(gè)頁面需要添加某個(gè)復(fù)雜的view的時(shí)候万伤,需要從現(xiàn)有的組件中拼裝罷了。
所以呜袁,React-Native事實(shí)上解決的是如何不使用Objc/Swift來寫iOS App的View的問題敌买,對(duì)于如何通過不發(fā)版來給已發(fā)版的App更新功能這樣的問題,幫助有限阶界。
4虹钮、Lua Patch
大眾點(diǎn)評(píng)的屠毅敏同學(xué)在基于wax的基礎(chǔ)上寫了waxPatch聋庵,這個(gè)工具的主要原理是通過lua來針對(duì)objc的方法進(jìn)行替換,由于lua本身是解釋型語言芙粱,可以通過動(dòng)態(tài)下載得到珍策,因此具備了一定的動(dòng)態(tài)部署能力。然而iOS系統(tǒng)原生并不提供lua的解釋庫(kù)宅倒,所以需要在打包時(shí)把lua的解釋庫(kù)編譯進(jìn)app。
優(yōu)點(diǎn)
能夠通過下載腳本替換方法的方式屯耸,修改本地App的行為拐迁。
執(zhí)行效率較高
缺點(diǎn)
對(duì)于替換功能來說,lua是很不錯(cuò)的選擇疗绣。但如果要添加新內(nèi)容线召,實(shí)際操作會(huì)很復(fù)雜
很容易改錯(cuò),小問題變成大問題
總結(jié)
lua的解決方案在一定程度上解決了動(dòng)態(tài)部署的問題多矮。實(shí)際操作時(shí)缓淹,一般不使用它來做新功能的動(dòng)態(tài)部署,主要還是用于修復(fù)bug時(shí)代碼的動(dòng)態(tài)部署塔逃。實(shí)際操作時(shí)需要注意的另外一點(diǎn)是讯壶,真的很容易改錯(cuò),尤其是你那個(gè)方法特別長(zhǎng)的時(shí)候湾盗,所以改了之后要徹底回歸測(cè)試一次伏蚊。
5、JSPatch
這個(gè)工作原理其實(shí)跟上面說的lua那套方案的工作原理一樣格粪,只不過是用javascript實(shí)現(xiàn)躏吊。而且最近新出了一個(gè)JSPatch這個(gè)庫(kù),相當(dāng)好用帐萎。
優(yōu)點(diǎn)
同Lua方案的優(yōu)點(diǎn)
打包時(shí)不用將解釋器也編譯進(jìn)去比伏,iOS自帶JavaScript的解釋器,只不過要從iOS7.0以后才支持疆导。
缺點(diǎn)
同Lua方案的缺點(diǎn)
總結(jié)
在對(duì)app打補(bǔ)丁的方案中赁项,目前我更傾向于使用JSPatch的方案,在能夠完成Lua做到的所有事情的同時(shí)澈段,還不用編一個(gè)JS解釋器進(jìn)去肤舞,而且會(huì)javascript的人比會(huì)lua的人多,技術(shù)儲(chǔ)備比較好做均蜜。
6李剖、JSON Descripted View
其實(shí)這個(gè)方案的原理是這樣的:使用JSON來描述一個(gè)View應(yīng)該有哪些元素,以及元素的位置囤耳,以及相關(guān)的屬性篙顺,比如背景色偶芍,圓角等等。然后本地有一個(gè)解釋器來把JSON描述的View生成出來德玫。
這 跟React-Native有點(diǎn)兒像匪蟀,一個(gè)是JS轉(zhuǎn)Native,一個(gè)是JSON轉(zhuǎn)Native宰僧。但是同樣有的問題就是事件處理的問題材彪,在事件處理 上,React-Native做得相對(duì)更好琴儿。因?yàn)镴SON不能夠描述事件邏輯段化,所以JSON生成的View所需要的事件處理都必須要本地事先掛好。
優(yōu)點(diǎn)
能夠自由生成View并動(dòng)態(tài)部署
缺點(diǎn)
天貓實(shí)際使用下來造成,發(fā)現(xiàn)還是存在一定的性能問題显熏,不夠快
事件需要本地事先寫好,無法動(dòng)態(tài)部署事件
總結(jié)
其實(shí)JSON描述的View比React-Native的View有個(gè)好處就在于對(duì)于這個(gè)View而言晒屎,不需要本地也有一套對(duì)應(yīng)的View喘蟆,它可以依據(jù) JSON的描述來自己生成。然而對(duì)于事件的處理是它的硬傷鼓鲁,所以JSON描述View的方案蕴轨,一般比較適用于換膚,或者固定事件不同樣式的View骇吭,比如 貼紙尺棋。
三、JSPatch的使用
1绵跷、JSPatch的基礎(chǔ)原理
JSPatch 能做到通過 JS 調(diào)用和改寫 OC 方法最根本的原因是 Objective-C 是動(dòng)態(tài)語言膘螟,OC 上所有方法的調(diào)用/類的生成都通過 Objective-C Runtime 在運(yùn)行時(shí)進(jìn)行,我們可以通過類名/方法名反射得到相應(yīng)的類和方法碾局。
理論上你可以在運(yùn)行時(shí)通過類名/方法名調(diào)用到任何 OC 方法荆残,替換任何類的實(shí)現(xiàn)以及新增任意類。所以 JSPatch 的基本原理就是:JS 傳遞字符串給 OC净当,OC 通過 Runtime 接口調(diào)用和替換 OC 方法内斯。
2、JSPatch的用法
a像啼、使用辦法參照官方文檔:http://www.jspatch.com/Docs/intro?
b俘闯、JSPatch的相關(guān)知識(shí)請(qǐng)參考github上的開源項(xiàng)目,這里能滿足絕大部分知識(shí)的學(xué)習(xí)