iOS 現(xiàn)在的 “熱修復(fù)/熱更新”

我先來拋一個(gè)??,為啥蘋果大大會(huì)禁用JSPatch的“熱更新”?以及iOS統(tǒng)計(jì)現(xiàn)階段可以通過審核的“熱更新”。
這個(gè)磚會(huì)在文中進(jìn)行探究和解答。

首先,在那2017年3月8…,記得那是給女神過節(jié)的那一天,蘋果爸爸大刀闊斧的砍向了JSPatch領(lǐng)銜的JS動(dòng)態(tài)代碼映射技術(shù),頓時(shí),感覺iOS熱更技術(shù)要變天,之后類似各家大廠SDK中使用了JSPatch的都紛紛移除相關(guān)代碼讓開發(fā)者進(jìn)行更新,直到現(xiàn)在JSPatch發(fā)布的1.8.0版本公告中說明都會(huì)大概率被拒,1.8.2的版本則在試驗(yàn)過程中:


image.png

但是為什么游戲中的熱更新技術(shù)不會(huì)受到蘋果的禁止,作為一名技術(shù)人員,不討論其他角度的問題,只從技術(shù)角度來看,為什么 JSPatch蘋果認(rèn)為是不允許的,而游戲引擎的熱更新技術(shù),蘋果認(rèn)為是可以的呢?
其實(shí)就是JSPatch能夠?qū)λ械?Objective-C 的 API 進(jìn)行映射,允許開發(fā)者在 JS 端調(diào)用任意原生代碼,這會(huì)造成重大的安全隱患問題。
游戲中的熱更新技術(shù)主要的實(shí)現(xiàn)方式是把動(dòng)態(tài)腳本下載之后,讓動(dòng)態(tài)腳本調(diào)用游戲引擎提供的接口實(shí)現(xiàn)缺陷修復(fù)。與 JSPatch不同的是,動(dòng)態(tài)腳本并不能任意調(diào)用全部原生代碼,而是只能根據(jù)游戲引擎提供的接口調(diào)用相關(guān)功能。在這個(gè)過程中,游戲引擎的原生端作為一個(gè)安全沙箱,提供了一個(gè)安全的保護(hù)層,只要游戲引擎不要對(duì)外提供獲取通訊錄的接口,黑客就無法通過替換動(dòng)態(tài)腳本的方式獲取用戶的隱私資料。進(jìn)而可以被認(rèn)為是安全的,自然就不在蘋果的禁止范圍內(nèi)。


WeChatb0d520737ce3a66f1da7b3cc7e46af6c.png

??總的來說:蘋果認(rèn)為JSPatch這個(gè)使用了dlopen(), dlsym(), respondsToSelector:, performSelector:,method_exchangeImplementations() 等反射函數(shù)動(dòng)態(tài)調(diào)用OC的API是危險(xiǎn)的,那現(xiàn)在iOS還有熱更新嗎,答案是肯定的,而且還不少,但是大部分都是JS開發(fā)的項(xiàng)目,這些項(xiàng)目肯定是可以熱更的,那iOS熱更有哪些呢,哪些是原生的呢,接下來我們就探究一下“市面上的熱更新/熱修復(fù)”。??????(當(dāng)然,企業(yè)賬號(hào)就用JSPatch就可以了)

一、游戲類的熱修復(fù)

像老的cocos2dx和新的creater,還有u3d都用的lua腳本拉??;

二、阿里百川Fix

原生可接入的SDK,這個(gè)條件是需要20萬的日活,才會(huì)給SDK;

三、Weex、RN、Hybrid等

本身由js編寫的代碼,自然可以進(jìn)行js進(jìn)行bundle拉取

四、TTPatch、MangoFix等修復(fù)

https://github.com/yangyangFeng/TTPatch
https://github.com/YPLiang19/Mango
兩個(gè)方案原生可都接入

TTPatch:是JSPatch的一個(gè)簡(jiǎn)化版,用的是js的解釋器,支持的語法也比較全面,底層原理和JSPatch是差不多的,中間通過替換方法的方式,將目標(biāo)方法的IMP替換為_objc_msgForward,直接開始消息轉(zhuǎn)發(fā),然后在經(jīng)過resolveInstanceMethod 、forwardingTargetForSelector、methodSignatureForSelector到forwardInvocation里獲取到執(zhí)行方法的invocation對(duì)象,之后進(jìn)行操作以及替換,不支持swift熱修復(fù)(可以集成用于動(dòng)態(tài)添加類)。

MangoFix:是DSL即 “領(lǐng)域?qū)S谜Z言”,用的是解析器進(jìn)行詞法、語法、語義檢查和分析,作者用到了libffi庫(用于高級(jí)語言之間的相互調(diào)用)進(jìn)行運(yùn)行時(shí)動(dòng)態(tài)創(chuàng)建C函數(shù),然后在創(chuàng)建的C函數(shù)中查找MangoFix腳本中方法并調(diào)用(這個(gè)用了類似dlsym的symdl進(jìn)行動(dòng)態(tài)調(diào)用函數(shù),
),然后用剛剛創(chuàng)建的C函數(shù)替換原來Method的IMP指針并保留原有的IMP指針,?? y1u1這個(gè)方案確實(shí)不錯(cuò),在語法上類似OC語法,上手挺快,但缺點(diǎn)也很顯著,畢竟解析方式都是作者寫的,在語法上支持的不全面,比如rac的語法就很頭疼,不支持swift熱修復(fù)(可以集成用于動(dòng)態(tài)添加類)。

??總結(jié)一下:游戲的熱修復(fù)指望不上,阿里和騰訊的SDK門檻點(diǎn)兒高,Weex、RN、Hybrid這三種方案原生App只能看看,則最后的兩種方案原生可以集成使用,目前均可以上架,筆者用的就是MangoFix做的小功能熱修復(fù),如果沒有拉取到需要修復(fù)腳本可以不初始化熱修復(fù)模塊,腳本信息加密然后拉取到沙盒后解密加載。

補(bǔ)充:使用stinger進(jìn)行aop的方案也可以實(shí)現(xiàn)熱修復(fù)/熱更新。
補(bǔ)充:flutter 官方聲明是暫時(shí)不支持熱更新的,但是flutter支持web開發(fā),于是“flutter+web技術(shù)對(duì)接”這個(gè)熱更方案出來了,大致上是還是用js加載更新方案。

其他

  1. 說明:
    總結(jié)不對(duì)的地方歡迎糾正?? ,本文僅供用于學(xué)習(xí)參考。

  2. 參考資料:
    TTPatch :https://github.com/yangyangFeng/TTPatch
    MangoFix :https://github.com/YPLiang19/Mango
    MangoFix原理分析 :http://www.itdecent.cn/p/a6511c687eda
    動(dòng)態(tài)調(diào)用&定義C函數(shù):http://www.itdecent.cn/p/92d4c06223e7
    Unity3D游戲輕量級(jí)xlua熱修復(fù)框架 :https://www.cnblogs.com/SChivas/p/7893048.html

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容