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

相关文章
相关标签/搜索