一、目的:
随着APP迭代更新,项目越写越庞大,每个功能间的关联性越来越多。再加上测试人员人手不足等情况,不可避免会发布带有bug的APP到appStore,所以我们就想尽快发布新版本进行覆盖。苹果公司对APP的审核速度现在虽然有所提高,但是仍需要时间。而在这段时间内很可能就会丧失大量用户。所以,在发现bug后立即解决并能同步到所有客户端内,这就是我们要达成的目的。然而使用JSPatch就可以解决这样的问题,只需在项目中引入JSPatch,就可以在发现bug时下发JS脚本补丁,替换原生方法,无需更新APP即时修复bug。
二、实现原理:
我们可以通过JavaScript代码来修改OC代码,归根结底还是OC运行时及消息转发机制。
三、JSPatch集成
1.cocoaPods集成
在Podfile文件引入:
pod 'JSPatchPlatform'
再pod update即可
2.手动集成
去网站下载SDK:http://jspatch.com/Index/sdk
下载完成后将JSPatchPlatform.framework 拖入工程后 在TARGETS ->Build Phases ->Link binary with libraries 添加libz.tbd
四、热更新和热修复的简单尝试
首先创建一个工程,使用上面的任意一种方式集成JSPatch,然后在viewController里添加如下代码(控件从storyboard拖拽的,代码亦可)。
测试代码.png
运行结果如下图所示:此时label的text为"原始文字",而button一点击就会crash。然而需求是:label的text为"修改后的文字",button点击后文字改为"按钮被点击了",那么在不上传新的APP到appStore时如何实现这个需求呢。这就要用到JSPatch了。
初始运行结果.png
1、在appDelegate引入头文件#import <JSPatchPlatform/JSPatch.h>并在didFinishLaunchingWithOptions方法里添加如下代码
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { //初始化SDK [JSPatch startWithAppKey:@"你的appKey"]; //进入开发模式(开发测试时调用) [JSPatch setupDevelopment]; // 同步脚本 [JSPatch sync]; return YES; }
2、获得你的appKey
- 需要先在平台注册用户http://jspatch.com/Index/reg
- 注册成功后然后添加要集成的APP
-
添加成功后会出现对应的appKey,这个就是上面需要你填写的appKey
添加成功.png
3、上传js脚本补丁进行修改/修复
-
添加版本。!注意:这个版本号要与你工程的版本号一致,否则无法下载响应的补丁。
添加版本.png - 上传js脚本,上传要求:JS脚本的文件名必须是main.js
1、创建一个空的main.js格式文件,添加如下代码
defineClass('ViewController', { test : function() { self.label().setText("修改后的文字"); } })
defineClass("ViewController", { btnClicked: function(sender) { sender.setTitle_forState("按钮被点击了", 0); } }, {});
ps:如果不熟悉js代码,可使用转换器将oc代码转换成js代码。http://jspatch.com/Tools/convertor
2、选择刚才创建的版本,进入如下界面,上传main.js文件,勾选开发预览,点击提交。
3、然后就到了你验证奇迹的时刻。运行你的项目试一下。!注:如果你的xcode8并且是用模拟器运行的则需要在项目 Capabilities 打开 Keychain Sharing 开关。
最终结果.png
看看你的运行结果是不是和我的一样,如果一样那么这个简单的尝试就结束了。但是JSPatch的操作还是挺繁多的,比如如何添加新方法、如何给一个类动态新增 Property等一系列操作任需要我们掌握。参见https://github.com/bang590/JSPatch/wiki/JSPatch-基础用法
当然我们也可以本地测试main.js文件是否正确且有用:首先将main.js文件拖入工程,再在didFinishLaunchingWithOptions方法里将[JSPatch startWithAppKey:@"你的appKey"];
替换为[JSPatch testScriptInBundle];
(注:这两个方法不能同时调用)。
PS:JSPatch 是一个开源项目,本文是在JSPatch平台的基础上操作的,如果想通过自己的服务器实现脚本的检测、下发等操作,可直接在github上下载源码进行操作。https://github.com/bang590/JSPatch
网友评论
pod repo remove master
pod setup
第二个命令可能时间会长些 耐心等待
pod 'JSPatchPlatfrom'
end
[!] Unable to find a specification for `JSPatchPlatfrom`
这样的提示,而且我 pod search jspatch也只出 "JSPatch(1.1)"、"JSPatch(1.5.2)"、"JSPatchSDKPod(1.5.2)"这三个。是我的cocoa pods有问题吗
target '你的工程名' do
pod 'JSPatchPlatform'
end