JSPatch 热修复技术

作者: SwiftCafe | 来源:发表于2017-01-22 09:30 被阅读170次

JSPatch 为我们的 iOS 程序提供了一个动态修改代码的能力。比如你的 APP 发生了线上 Bug,通过 JSPatch 不需要重新发版,就可以立即修复。

客户端开发的痛点

众所周知,我们做 APP 客户端开发一个很大的痛点就是,如果我们的 APP 在商店发布后,如果发生了比较验证的 bug, 我们是没有办法立即修复的。 对于 App Store 而言,最快也就是给商店递交紧急审核的请求,但这也需要重新发版,并且用户要更新 APP 后才可以修复。

随着 APP 开发生态越来越趋于成熟,相关的各种问题都有了比较好的解决方案。那么对于动态修复技术,也是一样。 JSPatch 就是解决这个问题的一个开源库。它包含一个解析引擎,可以将符合规则的 js 脚本,解析成 iOS 原生代码。这样我们就可以在不重新发布新版的情况下,修复我们线上的问题了。

JSPatch 简介

JSPatch 的使用非常简单,我们初始化 JS 解析引擎,然后传入脚本文件:

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 
{
    [JPEngine startEngine];
    NSString *sourcePath = [[NSBundle mainBundle] pathForResource:@"demo" ofType:@"js"];
    NSString *script = [NSString stringWithContentsOfFile:sourcePath encoding:NSUTF8StringEncoding error:nil];
    [JPEngine evaluateScript:script];

    self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
    [self.window addSubview:[self genView]];
    [self.window makeKeyAndVisible];

    return YES;
}

- (UIView *)genView
{
    return [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 320)];
}

@end

上面这段代码应该不难理解,首先我们调用 [JPEngine startEngine] 方法。接着找到 JS 脚本文件,并调用 [JPEngine evaluateScript:script] 执行这个脚本。

这里我们的脚本文件是存放在 Bundle 中的。 但这个脚本其实可以来自任何地方,包括从服务器中读取。这就为我们提供了动态下发脚本的能力。在任何时候,我们都可以下发脚本。

我们上面的代码中,还定义了一个 genView 方法,这个方法会返回一个 UIView 对象。这个方法正是我们要用 JSPatch 替换掉的。

再来看看 demo.js 文件:

// demo.js
require('UIView, UIColor, UILabel')
defineClass('AppDelegate', {
  // replace the -genView method
  genView: function() {
    var view = self.ORIGgenView();
    view.setBackgroundColor(UIColor.greenColor())
    var label = UILabel.alloc().initWithFrame(view.frame());
    label.setText("JSPatch");
    label.setTextAlignment(1);
    view.addSubview(label);
    return view;
  }
});

这个脚本的语法看起来或许会有些陌生。但我们稍加分析,也不难理解。 首先用 require('UIView, UIColor, UILabel') 导入我们要使用的组件。

然后,后面的 defineClass 方法,定义我们要对哪个类的内容进行替换。 这里我们替换了 AppDelegate 的 genView 方法。 然后再看看脚本中如何定义的 genView 函数体。

首先调用 self.ORIGgenView() 方法,稍微推理一下也容易明白,ORIG 是一个通用前缀,代表最初的方法,ORIGgenView 就是我们在上面 ObjC 代码中定义的 genView 方法了。

也就是说,这里先调用了我们最初的 genView 方法。 然后将它返回的 UIView 对象进行了一些列操作, 添加了一个 UILabel 到它上面。 最后再返回。

好了,现在如果运行这个 APP,实际上我们 genView 方法得到的就是脚本中描述的那样,一个 UIView 包含了一个 UILabel。 而不是 ObjC 中那个原始的方法了。

实践方案

正如上面例子中那样,JSPatch 可以在任何时候加载脚本文件。 它的原理大概就是基于 ObjC Runtime 的机制。将我们的代码在运行时进行替换。

将脚本直接放到 Bundle 里只是我们这个例子为了实验性目的才这样做。 一般来说 JSPatch 更多用于在线上动态进行修复。我们可以将脚本放到服务器中,本地 APP 去服务器中获取脚本,然后执行。

但要格外注意一点,就是脚本的传输安全。一件事情有利就会有弊。 虽然 JSPatch 给我们提供了非常强大的动态修复能力。但因为脚本可以通过远程动态下发,我们就要对安全性更加谨慎了。比如传输协议一定要使用 HTTPS,加大劫持难度。否则一些用户就有可能受到恶意攻击的伤害。

结语

JSPatch 总体上给我们提供了很强的动态修复能力。这点对于用户量比较大的 APP 就很有作用。 但大家在使用的时候,也要对安全实践更加注意。并且还是要将它用在适合它的场景之下,这样你的 APP 的效率和能力都会有很大的提升。

更多内容,大家可以参考 JSPatch 的 Github 主页 https://github.com/bang590/JSPatch

更多精彩内容可关注微信公众号:
swift-cafe

相关文章

  • JSPatch 热修复技术

    JSPatch 为我们的 iOS 程序提供了一个动态修改代码的能力。比如你的 APP 发生了线上 Bug,通过 J...

  • JSPatch 热修复实战技术

    其实,关于JSPatch热修复前面很早写过,因其只是从笔记本里抽取的一篇笔记,所以排版很潦草,有朋友跟我反馈希望用...

  • JSPatch热修复

    今天写了一个jspatch的小demo,每一步都做了截图,如果不了解JSPatch,大家可自行百度。JSPatch...

  • JSPatch热修复

    首先,简单说一下,为什么要用JSPatch,做iOS开发的人都知道,一旦程序出现了紧急BUG,各种申请苹果的...

  • JSPatch热修复

    iOS如果线下出现bug, 这个好解决, 但如果线上出bug, 由于APP Store提交审核有时间限制, 修改完...

  • JsPatch学习(1)【使用篇】

    JsPatch的使用很多,简单介绍热修复功能。JsPatch【使用篇】 最简单的使用: 1、注册App 到JSPa...

  • iOS 动态化热修复方案

    iOS 动态化热修复方案 Warnning 前言 iOS热修复方案经过JSPatch事件后,也消停了很久。bang...

  • IOS热修复JSPatch

    概述 JSPatch是什么? JSPatch 是一个Github开源项目(https://github.com/b...

  • 热修复-JSPatch源码

    JSPatch 简单版本的JSPatch和注释:https://github.com/misaka14/JSPat...

  • JSPatch实现热修复

    对于苹果的app来说,虽然在提交审核上线前会经过严格的测试,但是还是要保证有重大bug的情况下能够及时进行热修复,...

网友评论

    本文标题:JSPatch 热修复技术

    本文链接:https://www.haomeiwen.com/subject/dsonbttx.html