1, JSPatch熱更新
眾所周知,AppStore 上發(fā)布需要有個一非常惡心的審核期,而且很可能被拒絕掉,發(fā)布或者迭代一個 App一般耗時是5-10個工作日.但是如果線上版本出現(xiàn)了一些問題,或者公司市場部突然要做某些活動,這就會讓 iOS 的程序員手忙腳亂.現(xiàn)在市場上很多大公司比如淘寶,58同城等都采用了 OC 和 HTML5 混編方法處理我說的那幾個問題, 這是現(xiàn)在最好的熱更新解決方案 ,但是 iOS 程序員去寫 H5有點不現(xiàn)實
2,為什么能熱更新,原理
能做到通過JS調(diào)用和改寫OC方法最根本的原因是 Objective-C 是動態(tài)語言形用,OC上所有方法的調(diào)用/類的生成都通過 Objective-C Runtime 在運行時進(jìn)行炎滞,我們可以通過類名/方法名得到相應(yīng)的類和方法,進(jìn)一步用 js 的代碼來代替實現(xiàn)方法.
JSPatch用iOS內(nèi)置的JavaScriptCore.framework作為JS引擎久橙,但沒有用它JSExport的特性進(jìn)行JS-OC函數(shù)互調(diào),而是通過Objective-C Runtime,從JS傳遞要調(diào)用的類名函數(shù)名到Objective-C路鹰,再使用NSInvocation動態(tài)調(diào)用對應(yīng)的OC方法撤蟆。
3,優(yōu)缺點
1>.JS語言
JS比Lua在應(yīng)用開發(fā)領(lǐng)域有更廣泛的應(yīng)用,目前前端開發(fā)和終端開發(fā)有融合的趨勢牵舵,作為擴展的腳本語言柒啤,JS是不二之選。
2>.符合Apple規(guī)則
JSPatch更符合Apple的規(guī)則畸颅。iOS Developer Program License Agreement里3.3.2提到不可動態(tài)下發(fā)可執(zhí)行代碼担巩,但通過蘋果JavaScriptCore.framework或WebKit執(zhí)行的代碼除外,JS正是通過JavaScriptCore.framework執(zhí)行的没炒。
3>.小巧
使用系統(tǒng)內(nèi)置的JavaScriptCore.framework涛癌,無需內(nèi)嵌腳本引擎,體積小巧。
4>.支持block
wax在幾年前就停止了開發(fā)和維護(hù)拳话,不支持Objective-C里block跟Lua程序的互傳先匪,雖然一些第三方已經(jīng)實現(xiàn)block,但使用時參數(shù)上也有比較多的限制弃衍。
風(fēng)險
JSPatch讓腳本語言獲得調(diào)用所有原生OC方法的能力呀非,不像web前端把能力局限在瀏覽器,使用上會有一些安全風(fēng)險:
1>.若在網(wǎng)絡(luò)傳輸過程中下發(fā)明文JS镜盯,可能會被中間人篡改JS腳本岸裙,執(zhí)行任意方法,盜取APP里的相關(guān)信息速缆〗翟剩可以對傳輸過程進(jìn)行加密,或用直接使用https解決艺糜。
2>.若下載完后的JS保存在本地沒有加密剧董,在未越獄的機器上用戶也可以手動替換或篡改腳本。這點危害沒有第一點大破停,因為操作者是手機擁有者翅楼,不存在APP內(nèi)相關(guān)信息被盜用的風(fēng)險。若要避免用戶修改代碼影響APP運行辱挥,可以選擇簡單的加密存儲犁嗅。
4,如何使用
1,注冊賬號,以及app,會生成一個appkey
2,導(dǎo)入框架和依賴項和AppDelegate
在該平臺下載SDK解壓后將JSPatch.framework拖入項目
添加依賴框架libz.dylib和JavaScriptCore.framework
1中startWithAppKey傳入平臺申請的appKey,啟動JSPatch SDK,同時會自動執(zhí)行已下載到本地的patch.
2中sync與JSPatch平臺后臺更新晤碘,詢問是否有patch更新褂微,如果有更新會自動下載并執(zhí)行。startWithAppKey并不會詢問后臺patch更新园爷,必須調(diào)用sync方法宠蚂。注意:**實時性不高的App只需在didFinishLaunchingWithOptions處調(diào)用一次,用戶啟動時就會同步patch信息童社;實時性要求高的App求厕,在applicationDidBecomeActive處調(diào)用,用戶每次喚醒App時就同步一次后臺
在AppDelegate.m的didFinishLaunchingWithOptions中添加如下代碼:
//添加頭文件
#import <JSPatch/JSPatch.h>
//1
[JSPatch startWithAppKey:JSPatchKey] //JSPatchKey是創(chuàng)建App獲得的AppKey
//2
[JSPatch sync]
3,測試本地腳本
在上線之前需要對腳本進(jìn)行本地測試查看運行是否正常扰楼,注意JSPatch平臺規(guī)范呀癣,JS腳本文件名必須是main.js。SDK提供了方法+testScriptInBundle用于發(fā)布前測試弦赖,調(diào)用該方法后项栏,JSPatch會在當(dāng)前項目的bundle尋找main.js。
注意:+testScriptInBundle不能與+startWithAppKey一起調(diào)用蹬竖,+testScriptInBundle只能用于本地測試沼沈,測試完需刪除
4,發(fā)布版本
-
添加版本
- 發(fā)布補丁
5,自定義RSA密鑰和安全問題
為避免js腳本傳輸過程被中間人篡改流酬,我們需要對js文件進(jìn)行RSA簽名加密,具體流程:
服務(wù)端
計算js文件MD5值
用RSA私鑰對MD值加密列另,與JS文件一起下發(fā)給客戶端
客服端
拿到加密數(shù)據(jù)芽腾,用RSA公鑰解密出MD5值
本地計算返回的js文件MD5值
對比2個MD5值,相等則校驗通過页衙,保存JS文件到本地
當(dāng)保存到本地時摊滔,越獄機器會有點風(fēng)險,我們可以通過對稱加密保存拷姿,然后讀取時解密惭载。
客戶端和JSPatch后臺默認(rèn)有一對RSA密鑰旱函,默認(rèn)會對這對密鑰進(jìn)行加解密驗證响巢。也可以自定義RSA密鑰。
6,自定義RSA密鑰
生成RSA密鑰棒妨。在終端輸入下列代碼后再當(dāng)前目錄就有rsa_private_key.pem和rsa_public_key.pem踪古。密鑰長度可選1024/2048/3072/4096...
openssl > genrsa -out rsa_private_key.pem 1024 pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM -nocrypt rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem
2,SDK設(shè)置RSA Public Key∪唬客戶端接入SDK后調(diào)用+setupRSAPublicKey:
設(shè)置定義的RSA Public Key伏穆,必須在+sync
之前調(diào)用。Public Key以字符串方式傳入纷纫,換行處需要手動加換行符枕扫。
3,使用Private Key下發(fā)腳本。下發(fā)腳本時勾選使用自定義RSA Key 選項辱魁,選擇本地的rsa_private_key.pem與腳本一起上傳烟瞧。JSPatch平臺使用上傳的Private Key對腳本MD5值進(jìn)行加密,然后下發(fā)客戶端染簇〔蔚危客戶端通過第二部設(shè)置的Public Key對腳本進(jìn)行驗證,通過則運行锻弓。注意:上傳的rsa_private_key.pem只是一次性使用砾赔,用戶必須保存rsa_private_key.pem文件
7,Objc代碼轉(zhuǎn)JS代碼
JSPatch 的 OC 代碼轉(zhuǎn)化
JSPatch基礎(chǔ)用法
JSPatch官網(wǎng)
JSPatch文檔
demo地址