本文共 3178 字,大约阅读时间需要 10 分钟。
iOS App的更新始终是个头疼的问题,Apple一般的审核周期需要两周左右,如果出现严重的bug,可以申请下加急审核,即使这样,审核通过的时间也需要好几个小时,并且加急的次数也是有限的,不能一直使用。幸好现在有一款动态更新的服务平台:JSPatch ,使用它修改bug就得心应手啦。
JSPatch 是一个开源项目(),只需要在项目里引入极小的引擎文件,就可以使用 JavaScript 调用任何 Objective-C 的原生接口,替换任意 Objective-C 原生方法。目前主要用于下发 JS 脚本替换原生 Objective-C 代码,实时修复线上 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://test.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
脚本文件如下:
//JSdefineClass("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); } }}, {})
这样的话有个麻烦的问题,就是需要每个app自己搭建一个服务器,用于js脚本文件的管理。幸好,已经有人帮忙做了这样的事情
JSPatch 需要使用者有一个后台可以下发和管理脚本,并且需要处理传输安全等部署工作,JSPatch 平台帮你做了这些事,提供了脚本后台托管,版本管理,保证传输安全等功能,让你无需搭建一个后台,无需关心部署操作,只需引入一个 SDK 即可立即使用 JSPatch。
在 AppDelegate.m
里载入文件,并调用 +startWithAppKey:
方法,参数为第一步获得的 AppKey。接着调用 +sync
方法检查更新。例子:
#import假设已接入 JSPatch SDK 的某线上 APP 发现一处代码有 bug 导致 crash:@implementation AppDelegate- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { [JSPatch startWithAppKey:@"你的AppKey"]; [JSPatch sync]; ...}@end
@implementation XRTableViewController- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ NSString *content = self.dataSource[[indexPath row]]; //可能会超出数组范围导致crash XRViewController *controller = [[JPViewController alloc] initWithContent:content]; [self.navigationController pushViewController:controller];}@end上述代码中取数组元素处可能会超出数组范围导致 crash,对此我们写了如下 JS 脚本准备替换上述方法修复这个 bug:
//main.jsdefineClass("XRTableViewController", { tableView_didSelectRowAtIndexPath: function(tableView, indexPath) { var row = indexPath.row() if (self.dataSource().length > row) { //加上判断越界的逻辑 var content = self.dataArr()[row]; var controller = XRViewController.alloc().initWithContent(content); self.navigationController().pushViewController(controller); } }})注意在 JSPatch 平台的规范里,JS脚本的文件名必须是
main.js
。接下来就看如何把这个 JS 脚本下发给所有用户。 转载地址:http://vsvsi.baihongyu.com/