学习那么多,最后的结果还是要用实战来检验。
1,首先导入JSPatch
很简单要不是手动导入http://jspatch.com/Index/sdk再添加支持库
或者使用cocoapods 直接在podfile文件加入pod 'JSPatchPlatform' 然后pod install 就好了。
2,注册JSPatchPlatform账号
注册很简单,有一个邮箱就可以。成功之后添加自己的app项目,获取对应的appkey。添加一个版本,注意这个版本号要和你工程的版本号一致
3,工程中调用JSPatch方法
[JSPatch startWithAppKey:@"你的appkey"];
//调用你的appkey,会自动执行已下载到本地的 patch 脚本
//用来检测回调的状态,是更新或者是执行脚本之类的,相关信息,会打印在你的控制台
[JSPatch setupCallback:^(JPCallbackType type, NSDictionary *data, NSError *error) {
switch (type) {
case JPCallbackTypeRunScript:
NSLog(@"JPCallbackTypeRunScript--->执行脚本");
break;
case JPCallbackTypeUpdate:
NSLog(@"JPCallbackTypeUpdate--->脚本有更新");
break;
case JPCallbackTypeUpdateDone:
NSLog(@"JPCallbackTypeUpdateDone--->已拉取新脚本");
break;
case JPCallbackTypeUpdateFail:
NSLog(@"JPCallbackTypeUpdateFail--->脚本拉取错误");
break;
default:
break;
}
}];
JPCallbackType:
JPCallbackTypeUnknow = 0,
JPCallbackTypeRunScript = 1, //执行脚本
JPCallbackTypeUpdate = 2, //脚本有更新
JPCallbackTypeUpdateDone = 3, //已拉取新脚本
JPCallbackTypeCondition = 4, //条件下发
JPCallbackTypeGray = 5, //灰度下发
JPCallbackTypeUpdateFail = 6, //脚本拉取错误
根据这个JPCallbackType,你能清楚地跟踪脚本拉取、执行等各种状态。
/*
进入开发模式
平台下发补丁时选择开发预览模式,会只对调用了这个方法的客户端生效。
在 `+sync:` 之前调用,建议在 #ifdef DEBUG 里调。
*/
+ (void)setupDevelopment;
/*
与 JSPatch 平台后台同步,发请求询问后台是否有 patch 更新,如果有更新会自动下载并执行
可调用多次(App启动时调用或App唤醒时调)
*/
+ (void)sync;
这样整合下来,在appdelegate中的didFinishLaunchingWithOptions方法中调用。
[JSPatch startWithAppKey:@"你的appkey"];
[JSPatch setupCallback:^(JPCallbackType type, NSDictionary *data, NSError *error) {
switch (type) {
case JPCallbackTypeRunScript:
NSLog(@"JPCallbackTypeRunScript--->执行脚本");
break;
case JPCallbackTypeUpdate:
NSLog(@"JPCallbackTypeUpdate--->脚本有更新");
break;
case JPCallbackTypeUpdateDone:
NSLog(@"JPCallbackTypeUpdateDone--->已拉取新脚本");
break;
case JPCallbackTypeUpdateFail:
NSLog(@"JPCallbackTypeUpdateFail--->脚本拉取错误");
break;
default:
break;
}
}];
#ifdef DEBUG
[JSPatch setupDevelopment];
#endif
[JSPatch sync];
4,在ViewController中测试
在ViewController添加一个uilabel,展示文字初始为“哈哈哈哈哈哈”
在js脚本中代码
defineClass('ViewController', {
jsPatchTest : function() {
self.label().setText("label的text被改掉了");
},
})
效果如图
同时给一个按钮添加点击事件
[btn addTarget:self action:@selector(testJSPatch) forControlEvents:UIControlEventTouchUpInside];
js中代码
可以看到效果是
之后跳转到下一页也没问题。
5,总结
1>,这个是联网的调用,本地的引入这个头文件#import<JSPatchPlatform/JPEngine.h>后调用JPEngine相应方法
比如你的本地脚本是main.js,那么代码就是
[JPEngine startEngine];
NSString *sourcePath = [[NSBundle mainBundle] pathForResource:@"main" ofType:@"js"];
NSString *script = [NSString stringWithContentsOfFile:sourcePath encoding:NSUTF8StringEncoding error:nil];
[JPEngine evaluateScript:script];
他oc与js脚本中代码跟之前的一样。
这个本地js有一定的测试作用,比如你的联网的js拉取执行后,相应bug没有修复,或者方法没有执行,有可能是你的js脚本有问题。你可以在你的本地js测试方法和代码。
2>,xcode8.0 导入之后,要开启后台的capabilities -->keychain sharing,否则会在模拟器运行的时候报decompress error, md5 didn't match错误
3>,JSPatch想要漂亮的运用,oc或者swift代码转化成js脚本是关键之一。这里JSPatch大神bang590自己写的转换工具JSPatchConvertor很好用,但是也建议用这个JSPatchConvertor转换完成再去测试运行几次,确保js执行没问题。
4>,关于js脚本安全问题,网络上有好多,总结下来就一个方法那就是加密。比较推荐的一种的获取文件的MD5值比对+客户端与后台服务器一套公私密钥搭配起来更好。
其中获取文件MD5的方法如下
-(NSString *)Md5HashOfPath:(NSString *)path
{
NSFileManager *fileManager = [NSFileManager defaultManager];
// 文件是否存在.
if( [fileManager fileExistsAtPath:path isDirectory:nil] )
{
NSData *data = [NSData dataWithContentsOfFile:path];
unsigned char digest[CC_MD5_DIGEST_LENGTH];
CC_MD5( data.bytes, (CC_LONG)data.length, digest );
NSMutableString *output = [NSMutableString stringWithCapacity:CC_MD5_DIGEST_LENGTH * 2];
for( int i = 0; i < CC_MD5_DIGEST_LENGTH; i++ )
{
[output appendFormat:@"%02x", digest[i]];
}
return output;
}else{
return @"";
}
}
5>,JSPatch补丁的管理,管理记录每个补丁的状态。建议如果是bug或者需要修正的东西太多,在js紧急处理完后,在原生app中及时修改上传审核。
个人整理,不喜勿喷,谢谢!!
学习资料