前言

限于AppStore的审核机制,苹果应用审核通常需要一段时间。这对某些应用开发迭代比较快的公司来说,往往上一版本还在AppStore审核,新一版本已经开发完毕了,相对于Android的当天发布来说,已经算是不能再慢了。要是正好遇上线上有bug,那么又得重新回到AppStore提交-审核-发布的流程中去,但若是十分紧要的bug,不修复会影响应用的正常使用,那么再走这个流程就显得非常慢了。以前面对这种问题往往是走加急审核,但加急审核也会有3天时间,那能不能不发布版本在线上修复bug呢?答案是有的,这里选择的方案是JSPatch。

JSPatch简介

JSPatch是由国人开发的开源项目(Github链接)只需要在项目里引入极小的引擎文件,就可以使用 JavaScript 调用任何 Objective-C 的原生接口,替换任意 Objective-C 原生方法。目前主要用于下发 JS 脚本替换原生 Objective-C 代码,实时修复线上 bug。
关于JSPatch的实现原理可以参考作者的博客

语法

JSPatch使用简单明了,但需要注意的是JSPatch的语法,将OC语言转为JSPatch,例如:

  • OC
1
2
3
4
5
6
7
8
9
10
11
12
13
14
@implementation SampleClass
- (void)requestUrl:(NSString *)url param:(NSDictionary *)dict callback:(JPCallback)callback {
[super requestUrl:url param:dict callback:callback];
JPRequest *obj = [[JPRequest alloc] initWithUrl:url param:dict];
obj.successBlock = ^(id data, NSError *err) {
NSString *content = [JPParser parseData:data];
if (callback) callback(@{
@"content": content
}, err);
[self.dataSource refresh];
self.handleRequestSuccess(data);
};
}
@end
  • JSPatch
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
require('JPRequest,JPParser');
defineClass('SampleClass', {
requestUrl_param_callback: function(url, dict, callback) {
self.super().requestUrl_param_callback(url, dict, callback);
var obj = JPRequest.alloc().initWithUrl_param(url, dict);
obj.setSuccessBlock(block('id,NSError*', function(data, err) {
var content = JPParser.parseData(data);
if (callback) callback({
"content": content
}, err);

self.dataSource().refresh();
self.handleRequestSuccess()(data);
}))
;

},
});

作者提供了一个JSPatchConvertor简单粗暴,能满足一些简单的转换,比较复杂的就得人工修改了,更多语法上的可以参考JSPatchWiki

安全

使用 JSPatch 有两个安全问题:

  • 传输安全:JS 脚本可以调用任意 OC 方法,权限非常大,若被中间人攻击替换代码,会造成较大的危害。
  • 执行安全:下发的 JS 脚本灵活度大,相当于一次小型更新,若未进行充分测试,可能会出现 crash 等情况对 APP 稳定性造成影响。

作者推荐的一种方案如图所示:
JSPatchSecurity
1.服务端计算出脚本文件的 MD5 值,作为这个文件的数字签名。
2.服务端通过私钥加密第 1 步算出的 MD5 值,得到一个加密后的 MD5 值。
3.把脚本文件和加密后的 MD5 值一起下发给客户端。
4.客户端拿到加密后的 MD5 值,通过保存在客户端的公钥解密。
5.客户端计算脚本文件的 MD5 值。
6.对比第 4/5 步的两个 MD5 值(分别是客户端和服务端计算出来的 MD5 值),若相等则通过校验。
对于JSPatch若有更多安全上的顾虑可以参考作者的回应一下 JSPatch 安全问题

使用

目前有两种使用方法,一种是使用作者提供的JSPatch Platform平台,集成JSPatch的SDK,按请求次数收费,目前免费额度为 100w次请求/月,超出的部分会另行收费。
还有一种是自己造轮子,毕竟JSPatch是开源的,从前端逻辑到后台安全策略,都可以根据公司的业务需求自由定制。

后记

总体来说还是十分好用的,需要注意的是每次版本用JSPatch解决的线上Bug后,下个版本必须得将代码写入项目中。