webview 加載 html5 動态更新。
react native/weex js 動态更新。
其中 waxpatch 和 jspatch 是使用較廣泛的兩種熱修複方案。而蘋果 review guideline 提到隻允通過<code>javascriptcore.framework</code>或<code>webkit</code>執行腳本,是以 jspatch 是真正被 apple 官方支援的。此外鑒于<code>javascript</code>比<code>lua</code>語言更親民,使用系統内置的 <code>javascriptcore.framework</code>而無需内嵌lua腳本引擎來解釋運作lua代碼,jspatch 便成為目前 ios 熱修複使用最多,效果也最佳的方案。
有關上述幾種熱修複方案的比較可閱讀這兩篇文章:
<a href="http://awhisper.github.io/2016/07/22/weex-reactnative-jspatch/">weex & reactnative & jspatch</a>
jspatch 使用時需要一個背景下發和管理腳本。阿裡百川 hotfix 平台幫助開發者做了這些事。通過提供腳本托管、版本管理、腳本檔案及傳輸過程加密等服務,讓開發者無需搭建背景和關心部署操作,隻需引入一個 sdk 即可直接使用 jspatch 進行熱修複。這個 sdk 就是 apatch(ios)。
apatch 在 jspatch 核心代碼的基礎上封裝了向 hotfix 平台請求腳本/傳輸解密/腳本管理/本地調試等功能,是配合阿裡百川 hotfix 平台一起使用的。
從上圖可看出,用戶端從伺服器下載下傳 patch 之前先要下載下傳指定 patch 配置資訊即<code>patchinfo</code>,其中包含了 patch 檔案密鑰 <code>file_token</code>。
服務端:
對 <code>file_token</code> 用 rsa 公鑰加密。
對 <code>patchinfo</code> 原始資料采用 hmacsha1 算法計算的哈希值,并将原始資料和哈希值<code>servicetoken</code>放在同一消息中傳送給用戶端。
用戶端:
使用 <code>secret</code> 計算所接收資料的哈希值。
檢查計算所得的 hmac 是否與傳送的 hmac 比對。
隻有<code>patchinfo</code>通過校驗比對後才會去下載下傳<code>patch</code>。
另外,update patch 的接口已遷至 https,進一步保證了資料傳輸的安全。
本地存儲的腳本被篡改的機會小很多,隻在越獄機器上有點風險,對此 apatch sdk 對下載下傳的腳本進行了aes對稱加密,每次讀取時:
用戶端使用 rsa 私鑰解密 <code>patchinfo.file_token</code> 擷取 <code>key</code> 和 <code>iv</code>。
使用 <code>key</code> 和 <code>iv</code> 進行 aes 解密。
解密成功後的資料存儲在 <code>script</code> 中,然後會調用 jspatch 運作js腳本的接口:
至此,apatch 的工作已經完成,接下來具體的熱修複工作就交給 jspatch 了。
——jspatch wiki
“極小的引擎檔案”指的就是 javascriptcore。os x mavericks 和 ios 7 引入了 javascriptcore 庫,它把 webkit 的 javascript 引擎用 objective-c 封裝,提供了簡單、快速、安全的方式接入世界上最流行的語言:
在 objective-c 代碼中直接執行 javascript 代碼段;
在 javascript 語言環境裡調用 objective-c 公開給 javascript的 方法;
記憶體管理和線程封裝。
如果未接觸過 javascriptcore,在深入學習 jspatch 之前有必要先了解一下這個js引擎怎麼使用。
<code>jscontext</code> 是運作 javascript 代碼的環境。可以在 <code>jscontext</code>中建立變量、計算、定義方法等:
<code>jsvalue</code>包裝了每一個可能的 javascript 值,任何出自 <code>jscontext</code> 的值都被包裹在一個 <code>jsvalue</code> 對象中:
對 <code>jscontext</code> 和 <code>jsvalue</code> 執行個體使用下标可以通路之前建立的 context 的任何值。<code>jscontext</code> 需要一個字元串下标,<code>jsvalue</code> 使用字元串或整數下标來得到裡面的對象和數組:
調用js方法需要使用<code>callwitharguments:</code>傳遞參數:
這裡使用 foundation 類型<code>nsarray</code>作為參數來直接調用該函數。javascriptcore 可以 很輕松地處理這個橋接。
以上js代碼都以字元串形式直接出現在oc代碼中,實際中也可以在項目中引入.js檔案,執行js檔案中的内容。即:
從js通路在oc中定義的對象和方法有兩種方式:
定義一個<code>test</code>類,遵循 <code>jsexport</code>協定:
測試: