JSPatch 有了这个插件,不在受限于苹果漫长审核周期,功能更新随心所欲

作者介绍:bang

iOS/前端开发者

推特中文圈/伊书/JSPatch作者

博客 http://cnbang.net

目前就职于广州腾讯



在网上看到这个库比较牛逼,js可以调用所有的oc方法和类,操作简单,js语法和oc的语法基本一致,可以用js来编写native app 程序,可以实现不通过苹果审核更新app功能。不多说了,我下载了一个例子,跑起来给大家看看。


1.文件结构:



app开发报价单
app开发报价单
集成墙板
集成墙板
沥青期货
沥青期货
家装样板房
家装样板房


2.js编写的tableView功能可UIbutton事件:



app制作
app制作
app开发报价单
app开发报价单
app开发外包
app开发外包
h5页面制作
h5页面制作
集成墙板
集成墙板
o2o便利店
o2o便利店


3.view中的button事件:



h5页面制作
h5页面制作
app开发报价单
app开发报价单
森歌集成灶
森歌集成灶
集成墙板
集成墙板
苹果6分期付款
苹果6分期付款
集成灶十大品牌
集成灶十大品牌

4.AppDelegate调用JsPatch功能




5.运行效果:



下面是js实现的tableView功能:




以下是作者的讲解:

用途

是否有过这样的经历:新版本上线后发现有个严重的 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,持续改进中。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值