JSPatch – 動態更新iOS APP

來源:互聯網
上載者:User

標籤:

JSPatch是最近業餘做的項目,只需在項目中引入極小的引擎,就可以使用JavaScript調用任何Objective-C的原生介面,獲得指令碼語言的能力:動態更新APP,替換項目原生代碼修複bug。

用途

是否有過這樣的經曆:新版本上線後發現有個嚴重的bug,可能會導致crash率激增,可能會使網路請求無法發出,這時能做的只是趕緊修複bug然後提交等待漫長的AppStore審核,再盼望使用者快點升級,付出巨大的人力和時間成本,才能完成此次bug的修複。

使用JSPatch可以解決這樣的問題,只需在項目中引入JSPatch,就可以在發現bug時下發JS指令碼補丁,替換原生方法,無需更新APP即時修複bug。

例子

@implementation JPTableViewController
...
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
  NSString *content = self.dataSource[[indexPath row]];  //可能會超出數組範圍導致crash
  JPViewController *ctrl = [[JPViewController alloc] initWithContent:content];
  [self.navigationController pushViewController:ctrl];
}
...
@end
上述代碼中取數組元素處可能會超出數組範圍導致crash。如果在項目裡引用了JSPatch,就可以下發JS指令碼修複這個bug:

#import “JPEngine.m"
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    [JPEngine startEngine];
    [NSURLConnection sendAsynchronousRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://cnbang.net/bugfix.JS"]] queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
    NSString *script = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
    if (script) {
      [JPEngine evaluateScript:script];
    }
}];
   ….
    return YES;
}
@end
//JS
defineClass("JPTableViewController", {
  //instance method definitions
  tableView_didSelectRowAtIndexPath: function(tableView, indexPath) {
    var row = indexPath.row()
    if (self.dataSource().length > row) {  //加上判斷越界的邏輯
      var content = self.dataArr()[row];
      var ctrl = JPViewController.alloc().initWithContent(content);
      self.navigationController().pushViewController(ctrl);
    }
  }
}, {})
這樣 JPTableViewController 裡的 -tableView:didSelectRowAtIndexPath: 就替換成了這個JS指令碼裡的實現,在使用者無感知的情況下修複了這個bug。

更多的使用文檔和demo請參考github項目首頁。

原理

JSPatch用iOS內建的JavaScriptCore.framework作為JS引擎,但沒有用它JSExport的特性進行JS-OC函數互調,而是通過Objective-C Runtime,從JS傳遞要調用的類名函數名到Objective-C,再使用NSInvocation動態調用對應的OC方法。詳細的實現原理以及實現過程中遇到的各種坑和hack方法會另有文章介紹。

方案對比

目前已經有一些方案可以實現動態打補丁,例如WaxPatch,可以用Lua調用OC方法,相對於WaxPatch,JSPatch的優勢是:

1.JS語言

JS比Lua在應用開發領域有更廣泛的應用,目前前端開發和終端開發有融合的趨勢,作為擴充的指令碼語言,JS是不二之選。

2.符合Apple規則

JSPatch更符合Apple的規則。iOS Developer Program License Agreement裡3.3.2提到不可動態下發可執行代碼,但通過蘋果JavaScriptCore.framework或WebKit執行的代碼除外,JS正是通過JavaScriptCore.framework執行的。

3.小巧

使用系統內建的JavaScriptCore.framework,無需內嵌指令碼引擎,體積小巧。

4.支援block

wax在幾年前就停止了開發和維護,不支援Objective-C裡block跟Lua程式的互傳,雖然一些第三方已經實現block,但使用時參數上也有比較多的限制。

相對於WaxPatch,JSPatch劣勢在於不支援iOS6,因為需要引入JavaScriptCore.framework。另外目前記憶體的使用上會高於wax,持續改進中。

風險

JSPatch讓指令碼語言獲得調用所有原生OC方法的能力,不像web前端把能力局限在瀏覽器,使用上會有一些安全風險:

1.若在網路傳輸過程中下發明文JS,可能會被中間人篡改JS指令碼,執行任意方法,盜取APP裡的相關資訊。可以對傳輸過程進行加密,或用直接使用https解決。

2.若下載完後的JS儲存在本地沒有加密,在未越獄的機器上使用者也可以手動替換或篡改指令碼。這點危害沒有第一點大,因為操作者是手機擁有者,不存在APP內相關資訊被盜用的風險。若要避免使用者修改代碼影響APP運行,可以選擇簡單的加密儲存。

其他用途

JSPatch可以動態打補丁,自由修改APP裡的代碼,理論上還可以完全用JSPatch實現一個業務模組,甚至整個APP,跟wax一樣,但不推薦這麼做,因為:

JSPatch和wax一樣都是通過Objective-C Runtime的介面通過字串反射找到對應的類和方法進行調用,這中間的字串處理會損耗一定的效能,另外兩種語言間的類型轉換也有效能損耗,若用來做一個完整的業務模組,大量的頻繁來回互調,可能有效能問題。
開發過程中需要用OC的思維寫JS/Lua,喪失了指令碼語言自己的特性。
JSPatch和wax都沒有IDE支援,開發效率低。
若想動態為APP添加模組,目前React Native給出了很好的方案,解決了上述三個問題:

JS/OC不會頻繁通訊,會在事件觸發時批量傳遞,提高效率。(詳見React Native通訊機制詳解)
開發過程無需考慮OC的感受,遵從React架構的思想進行純JS開發就行,剩下的事情React Native幫你處理好了。
React Native連IDE都準備好了。
所以動態添加業務模組目前還是推薦嘗試React Native,但React Native並不會提供原生OC介面的反射調用和方法替換,無法做到修改原生代碼,JSPatch以小巧的引擎補足這個缺口,配合React Native用統一的JS語言讓一個原生APP時刻處於可擴充可修改的狀態。

目前JSPatch處於開發階段,穩定性和功能還存在一些問題,歡迎大家提建議/bug/PR,一起來做這個項目。

JSPatch – 動態更新iOS APP

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.