基于我本人的应用Hello LeetCode进行演示。
腾讯使用的Bugly热更新核心也是基于JSPatch的,阿里百川的热更新方案也是以JSPatch为核心的,甚至 官方 也推出了集成方案。这里选择Bugly单纯是因为Bugly的崩溃报告服务很好用,顺手一起用上热更新服务了。
使用Cocoapods集成
pod 'BuglyHotfix'
注意如果之前已经在Cocoapods中集成Bugly的话,需要将 pod Bugly
注释掉。因为 BuglyHotfix
本身已经带有Bugly的功能了。
BuglyHotfix在安装的过程中会自动安装JSPatch依赖,如下图:
安装好之后打开工程,注意如果之前是使用Bugly的服务,此时需要将旧有的 #import <Bugly/Bugly.h>
改为 #import <BuglyHotfix/Bugly.h>
,否则工程会报错。
在应用启动之后进行BuglyHotfix初始化:
-(void)initBugly{ BuglyConfig *config = [[BuglyConfig alloc]init]; //这里的hotfixDebugMode是作为本地调试用的,如果需要在本地调试js补丁,那么需要设置为YES config.hotfixDebugMode = YES; [Bugly startWithAppId:[ALConstant buglyAppId] #ifdef DEBUG developmentDevice:YES #endif config:config]; }
在工程中新建JS文件 main.js
,书写补丁逻辑,这部分的语法可以查看 这里 。
编辑完成之后运行,如果是本地调试,直接可以看到补丁结果。
等确认补丁写好之后,需要回到初始化方法中 initBugly
将 hotfixDebugMode
改为NO。这时候本地热更新不再起作用。将补丁文件打包为zip压缩文件。准备上传补丁。
BuglyHotfix的主要作用就是补丁的版本管理很方便。登录Bugly,点击应用升级,如图:
接着点击发布,弹出编辑窗口
上传补丁文件,在下发范围中可以根据需要进行范围选择,如果选择是开发设备的话,可以提前在真机中进行测试。如果判断补丁是正确的之后,再编辑为全量设备进行全范围发布。
注:如果是首次运行应用应该不会立即更新,推测此时在下载补丁。第二次运行就可以看到效果了。
这里简要讲解了JSPatch的基础用法,基本是按照 官方文档 来的。需要声明的一点,JSPatch很类似JS语法,但是毕竟不是JS语法,一些JS的高级用法还是无法进行使用。
任何需要调用的类型,都需要使用 require
关键字提前声明。不论是第三方类或者是自己写的类:
require('WebViewJavascriptBridge,Masonry') require('NSUserDefaults,UIDevice,NSBundle,UIStoryboard') require('AppLauncher')
对于一些OC默认类型,需要自动转换为JS类型,比如 @[]
-> []
这样的,需要进行声明
autoConvertOCType(1);
对于一些常用操作,可以声明宏定义,比如:
SCREEN_WIDTH = require('UIScreen').mainScreen().bounds().width; SCREEN_HEIGHT = require('UIScreen').mainScreen().bounds().height;
//在第二个参数处填上需要动态添加的属性 defineClass("DDWebViewController",['bridge'], { viewDidLoad: function() { //如果想要在原有方法逻辑下继续修改,需要执行原函数(ORIG+方法名) self.ORIGviewDidLoad(); //避免循环引用 var slf = self; }, }});
因为全部都是以方法的形式进行转换,所以原本
window.bounds
会变成
window.bounds()
原本属性赋值可能会变得更加繁琐,类似于原本OC代码:
shareTableview.delegate = self;
会需要这样写:
shareTableview.setDelegate(slf);
原本的OC方法将会变为以下划线链接的样式,参数全部依次放在括号中,比如原有的OC代码:
[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(loginSuccessFunction) name:@"USER_LOGIN_SUCCESS" object:nil];
变为:
NSNotificationCenter.defaultCenter().addObserver_selector_name_object(slf,"loginSuccessFunction","USER_LOGIN_SUCCESS",null) //SEL类型变为JS中的字符串 //nil 变为 null
由于block在OC实际上也是一种特殊的类型,在转换的时候作为参数进行转换,不过需要作为block类型进行传值。原本的OC代码可能是:
[bridge registerHandler:@"ocShare" handler:^(id data, WVJBResponseCallback responseCallback) {}];
会变为:
bridge.registerHandler_handler("ocShare",block("id,id",function(data,responseData){ //使用data作为参数 //使用responseData作为回调 if(responseData!=null) { responseData(result) } }))
OC代码转JSPatch网页