IOS热修复之JSPatch
![](https://i-blog.csdnimg.cn/blog_migrate/d6c2528520c0cd097c42f0ab172a8f14.webp?x-image-process=image/format,png)
前言
IOS热修复一直是关注的重点之一。由于appstore的审核上架机制的局限,新发布的版本往往要等待很长时间才能上架。如果旧版本有重大bug,并且用户不更新,那么安装了有bug版本的用户永远都不能修复(不可挽回的失误)。
所谓热修复,就是不需要重新上架就修复线上bug。去年比较流行的React Native
可以解决这一问题。但是React Native
需要用JS
编写代码,这一点对于我来说还是很不情愿的。
IOS热修复技术我一直认为很不成熟,但是当我使用JSPatch
的时候,我的观念完全改变了,这简直就是不可多得的神器!JSPatch
是去年3月份第一次在GitHub上提交,也算是新事物吧。
![](https://i-blog.csdnimg.cn/blog_migrate/d9a8d2a8f6d3352a1715e9660751e163.webp?x-image-process=image/format,png)
JSPatch简介
-
JSPatch 可以让你用 JavaScript 书写原生 iOS APP。只需在项目引入极小的引擎,就可以使用 JavaScript 调用任何 Objective-C 的原生接口,获得脚本语言的优势:为项目动态添加模块,或替换项目原生代码动态修复 bug。
-
作者Bang (以前一直觉得Bang博客很有清爽,特别喜欢,没想到是JSPatch的作者。。)
-
cocoaPods安装:
pod 'JSPatchSDK', '~> 1.5.2'
-
gitHub地址:https://github.com/bang590/JSPatch/blob/master/README-CN.md
-
实现原理:可以参考唐巧的文章戳这里
-
脚本管理平台:http://jspatch.com/
-
objective-c转js工具:转换工具
JSPatch实战体验(线下)
首先我们创建一个简单的项目,导入podFile,然后添加一个Label,添上约束,随便写点字。代码如下:
- (void)viewDidLoad {
[super viewDidLoad];
self.testLabel.text = @"this is a bug";
}
![](https://i-blog.csdnimg.cn/blog_migrate/6fab727b76e900ee942f337a4eff7395.webp?x-image-process=image/format,png)
然后在AppDelegate.m
中写上头文件和代码#import <JSPatch/JSPatch.h>
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
//线下使用这个代码,系统会自动查找项目中的main.js文件,然后完成热修复
[JSPatch testScriptInBundle];
return YES;
}
最后在项目中添加main.js
文件,里面写上js代码,运行就好了。不知道怎么写js?作者早就考虑到了这点,为了方便开发者,作者写了一个oc转js的脚本工具,只要在左侧写入oc代码,右边就能装换成符合规范的js文件(真的很用心)。
工具地址
![](https://i-blog.csdnimg.cn/blog_migrate/49eff8a9c214b3f7a8f00edb75a478d0.webp?x-image-process=image/format,png)
![](https://i-blog.csdnimg.cn/blog_migrate/850531ef57349e44cae3c86b192a5d1b.webp?x-image-process=image/format,png)
最后运行项目看看效果吧。
![](https://i-blog.csdnimg.cn/blog_migrate/53cdef93dc9f5d298dfa0610f1a2f92a.webp?x-image-process=image/format,png)
defineClass('ViewController', {
viewDidLoad: function() {
self.super().viewDidLoad();
self.testLabel().setText("Hot Fix!");
},
});
从js代码我们可以得出JSPatch
的实现原理。首先找到ViewController
类,再找到viewDidLoad:
方法,将js
用正则匹配或者其他方法转换成oc代码,在通过runtime
机制将viewDidLoad:
替换成新的方法,这样就实现了热修复。
我们再写点复杂的代码,给view上加一个Label。
![](https://i-blog.csdnimg.cn/blog_migrate/e11695afa0128bcd44d025e1fbe7d43f.webp?x-image-process=image/format,png)
这里需要注意的是,CGRectMake
等结构体转成js的时候,工具并不能帮我们转换成功,这也是一处Bug吧。可以参考文档:文档
正确代码如下:
require('UILabel,UIColor');
defineClass('ViewController', {
viewDidLoad: function() {
self.super().viewDidLoad();
self.testLabel().setText("hotFix!");
var label = UILabel.alloc().initWithFrame({x:100, y:100, width:100, height:100});
label.setText("hello World");
label.setBackgroundColor(UIColor.redColor());
self.view().addSubview(label);
},
});
效果:
![](https://i-blog.csdnimg.cn/blog_migrate/3a5ecddc9ece8e242da72022edc971e7.webp?x-image-process=image/format,png)
JSPatch实战体验(线上)
热修复,当然在线上测试才有意义。首先登入JSPatch平台(有能力的完全可以自己搭建)http://jspatch.com/注册一个账号,申请一个appKey。
![](https://i-blog.csdnimg.cn/blog_migrate/61ce04c1d609d328641942553335a32c.webp?x-image-process=image/format,png)
然后修改AppDelegate.m
里的方法,改成线上测试。
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[JSPatch startWithAppKey:@"728a7c0548d35106"];
#ifdef DEBUG
[JSPatch setupDevelopment];
#endif
[JSPatch sync];
// [JSPatch testScriptInBundle];
return YES;
}
把工程里的main.js
移出工程,上传到平台上。这样就完成了,线上的配置。运行代码,第一次还是显示this is a bug,因为工程要把线上的main.js
文件下载到本地。第二次进入就能看见hot Fix啦。
![](https://i-blog.csdnimg.cn/blog_migrate/7c1c46fa099397d352ff2e8c76fc5274.webp?x-image-process=image/format,png)
总结
总体体验下来,JSPatch
的使用真的很简单!而且作者真的很用心,为开发者专门设计了转换工具(对于js三脚猫功夫的我简直痛哭流涕),不愧为IOS热修复第一方案。
值得注意的是,有热修复就有安全问题。如果泄露修复方法,黑客就能修改你的源代码,这一点十分恐怖。JSPatch管理平台上提供了很多加密方案比如RSA等,具体的可以自行查看开发文档开发文档。
最后附上目前正在使用的app截图,阵容很强大哦~
![](https://i-blog.csdnimg.cn/blog_migrate/21c1d323c843c3bdd428fe95529bbca6.webp?x-image-process=image/format,png)
我是翻滚的牛宝宝,欢迎大家评论交流~