iOS解决方案JSPatch

来源:互联网 发布:琅琊榜骑兵进阶数据 编辑:程序博客网 时间:2024/05/24 02:39


更新完毕

iOS App审核是所有iOS开发者心中的一座山,漫长的等待时间如果在正常的版本更新时还好,但是在线上出现严重BUG时,没一分每一秒对我们来说都是一种煎熬,面对这样的问题,难道腾讯,阿里都跟我们一样吗?

当然不是

看看他们的解决方案:

1、微信为代表的JSPatch:https://github.com/bang590/JSPatch
2、阿里为代表的Wax:https://github.com/alibaba/wax



好几次App刚刚审核通过,却发现其中有致命的BUG,修改的话可能就是一两行代码就能搞定,但是苹果的审核时间让你起码几天面对这个BUG提心吊胆,对于饱受这份折磨的我来说,JSPatch简直就是救世主,话不多说,看都有谁在用这个:图片源自http://using.jspatch.org/ 【JSPatch使用统计社区】
image


这些大厂都在用着一套可以实现hit code push的解决方案让我们来认识一下JSPatch吧,原作者博客地址:

http://blog.cnbang.net/


JSPatch原理

JSPatch的基本原理就是通过JS代码,利用OC运行时的特性,已达到修改程序代码,让App具备hit code push的能力,更详细的原理可以去看上面原作者的博客,里面非常详细的讲解了JSPatch的底层实现。

JS文件通过从服务器下载到本地,所有使用时需要服务器的一定配合。

JSPatch的两个安全问题

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

所以,使用时对js文件的内容进行加密是必须的

JSPatch的使用

先去GitHub上下载源码,加入到工程中imageJSPatch经过作者的多次优化,在不断完善的过程中还是保持了极小的代码量,只有一千多行 OC 和接近两百行 JS(PS:再次膜拜一下大神)
这里使用到了JavaScriptcore核心库,所以还需要在General的Linded Framework and Libraries添加JavaScriptcore.frameworkimage


首先在AppDelegate中添加JPEngine.h的头文件然后添加下面两个方法:

// Library/Caches#define FilePath ([[NSFileManager defaultManager] URLForDirectory:NSCachesDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:YES error:nil])/** *  下载JSPatch */-(void)loadJSPatch{    //使用AFNetWork下载在服务器的js文件    NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];    AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration];    NSURL *URL = [NSURL URLWithString:@"http://blog.methodname.com/content/test.js"];    NSURLRequest *request = [NSURLRequest requestWithURL:URL];    NSURLSessionDownloadTask *downloadTask = [manager downloadTaskWithRequest:request progress:nil destination:^NSURL *(NSURL *targetPath, NSURLResponse *response)          {              NSURL *documentsDirectoryURL = FilePath;              //保存到本地 Library/Caches目录下              return [documentsDirectoryURL URLByAppendingPathComponent:[response suggestedFilename]];          }            completionHandler:^(NSURLResponse *response, NSURL *filePath, NSError *error)          {              NSLog(@"File downloaded to: %@", filePath);          }];    [downloadTask resume];}/** *  运行下载的JS文件 */-(void)HSDevaluateScript{    //从本地获取下载的JS文件    NSURL *p = FilePath;    //获取内容    NSString *js = [NSString stringWithContentsOfFile:[p.path stringByAppendingString:@"/test.js"] encoding:NSUTF8StringEncoding error:nil];    //如果有内容    if (js.length > 0)    {        //-------        //在此处解密js内容        //----        //运行        [JPEngine startEngine];        [JPEngine evaluateScript:js];    }}//还是在AppDelegate中下面的两个方法内,进行下载服务器的js文件和运行下载后的js文件//加载配置- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{//可以在这里设置一个条件,比如隔多久才去请求一次服务器看看有没有可以下载的文件//以防止频繁请求    [self loadJSPatch];    return YES;}//应用程序进入活动状态时- (void)applicationDidBecomeActive:(UIApplication *)application{    [self HSDevaluateScript];}

以上在客户端的配置就完成了

然后就是最关键的,如何使用js来完成调用,替换,覆盖原来的代码

JSPatch OC-JS自动转换工具:https://github.com/bang590/JSPatchConvertor

如果不想去记它的语法,完全可以用这个工具来进行OC,JS的转换,工具也是原作者写的(PS:再次膜拜大神,虽然有些语法上的瑕疵,具体请看github上的wiki)

//在MainViewController的viewDidLoad方法中将self.view的背景颜色改为橙色//-------OC代码@implementation MainViewController-(void)viewDidLoad{    [super viewDidLoad];    [self.view setBackgroundColor:[UIColor orangeColor]];}//------转换后的JS代码require('UIColor,UIViewController');//这里少了个UIViewController加上就好defineClass('MainViewController', {    viewDidLoad: function() {        super.viewDidLoad();        self.view().setBackgroundColor(UIColor.orangeColor());    },});

将这个文件,放在服务器上面,最好进行版本分类,这样在App下载的时候,就能根据当前的版本号来进行对应目录下的文件的下载例如:

AppName-->2.1-->jspatch.js
AppName-->2.2-->jspatch.js
AppName-->2.3-->jspatch.js

这样就能在App上根据目录:AppName(当前App版本号)\jspatch.js 这样的方式去下载对应版本的js文件了


注意事项:

引用某位使用过JSPatch大神博客里最后的话http://www.cnblogs.com/dsxniubility/p/5080875.html

1、接入了JSPatch之后,iOS的线上BUG 看上去就不向以前那样“猛如虎”了,但是这仅仅是一个紧急预案措施,以前规范的流程还是需要遵守。

2、每一次本版本用JSPatch解决的线上Bug,下个版本必须用OC代码写入项目中,不能允许补丁代码的存留超过一个版本。

3、倡导使用敏捷开发的思想,类似于主逻辑或者是功能模块入口的方法可以抽的更细,这样即使需要修改,成本也不会太大,作者本人也提到,如果有一行代码必须要在一个大方法的中间进行修改,那我也没办法了,你只能把这整个方法都用js写一遍了,所以才设置了JSPatchConvertor。

4、每次用JSPatch解决掉的线上BUG 应当有一个专门的文档记录,遇到重复错误必须写casestudy。

5、具体的使用请查看github上的wiki JSPatch wiki

最后:放上JSPatch的官网

目前jspatch的作者已经将jspatch商业化,并提供了完善的版本控制,脚本下发SDK,集成到APP中也只需要一行代码。JSPatch

原创粉丝点击