JSPatch – 動態更新iOS APP

使用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:web

#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。數組

風險:
瀏覽器

JSPatch讓腳本語言得到調用全部原生OC方法的能力,不像web前端把能力侷限在瀏覽器,使用上會有一些安全風險:安全

1.若在網絡傳輸過程當中下發明文JS,可能會被中間人篡改JS腳本,執行任意方法,盜取APP裏的相關信息。能夠對傳輸過程進行加密,或用直接使用https解決。網絡

2.若下載完後的JS保存在本地沒有加密,在未越獄的機器上用戶也能夠手動替換或篡改腳本。這點危害沒有第一點大,由於操做者是手機擁有者,不存在APP內相關信息被盜用的風險。若要避免用戶修改代碼影響APP運行,能夠選擇簡單的加密存儲。app

相關文章
相關標籤/搜索