Skip to content

ios 动态修复bug补丁第三方库JSPatch 使用学习:JSPatch导入、和使用、.js文件传输加解密

Notifications You must be signed in to change notification settings

macosunity/JSPatchUse

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

11 Commits
 
 
 
 
 
 

Repository files navigation

JSPatchUse JSPatchUse

JSPatchUse

JSPatch 代码更新 使用学习


使用文档

JSPatch使用文档

JSPatch Use Word file

使用方法

步骤1:创建项目中导入JSPatch库

    切换到项目命令:
    cd /Users/..(项目地址)

    编辑或创建Podfile命令:
    vim Podfile

    输入"i"进入编辑内容状态,添加:
    platform :ios, '6.0'
    pod 'JSPatch'
    粘贴后,按"esc",输入":",再输入"wq",回车】

    安装命令:
    pod install

步骤2:下载demo.js 文件到项目,修改AppDelegate.m文件:

    1、 #import "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:@"https://github.com/niexiaobo/JSPatchUse/blob/master/JSPatchUseDemo/JSPatchUseDemo/demo.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:@"/demo.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];
    }

    2、这里使用到了JavaScriptcore核心库,所以还需要在General的Linded Framework and Libraries添加JavaScriptcore.framework 

步骤3:修复控制器的崩溃bug:

控制器ViewController添加按钮,但是不写点击事件
    UIButton *crashBtn = [[UIButton alloc] initWithFrame:CGRectMake(0, 100, [UIScreen mainScreen].bounds.size.width, 50)];
    [crashBtn setTitle:@"崩溃按钮" forState:UIControlStateNormal];
    [crashBtn addTarget:self action:@selector(crashBtnClick:) forControlEvents:UIControlEventTouchUpInside];
    [crashBtn setBackgroundColor:[UIColor grayColor]];
    [self.view addSubview:crashBtn];


    //崩溃按钮 的点击事件【崩溃测试,不写】,js里会重写此方法避免崩溃。
    //- (void)crashBtnClick:(id)sender.
demo.js里添加代码:1、重写crashBtnClick方法 2、跳转新建的JPTableViewController控制器
    //1、修改ViewController控制器的handleBtn方法(原控制器漏此方法,会导致崩溃)。

    defineClass('ViewController', {//defineClass:声明要被修改的控制器
    crashBtnClick: function(sender) { //声明要被修改或重写的方法
    var tableViewCtrl = JPTableViewController.alloc().init()
    self.navigationController().pushViewController_animated(tableViewCtrl, YES)
    },

    })

    //2、新建JPTableViewController控制器

    defineClass('JPTableViewController : UITableViewController <UIAlertViewDelegate>', ['data'], {
    dataSource: function() {
    var data = self.data();
    if (data) return data;
    var data = [];
    for (var i = 0; i < 20; i ++) {
    data.push("通过js创建的cell " + i);
    }
    self.setData(data)
    return data;
    },
    numberOfSectionsInTableView: function(tableView) {
    return 1;
    },
    tableView_numberOfRowsInSection: function(tableView, section) {
    return self.dataSource().length;
    },
    tableView_cellForRowAtIndexPath: function(tableView, indexPath) {
    var cell = tableView.dequeueReusableCellWithIdentifier("cell") 
    if (!cell) {
    cell = require('UITableViewCell').alloc().initWithStyle_reuseIdentifier(0, "cell")
    }
    cell.textLabel().setText(self.dataSource()[indexPath.row()])
    return cell
    },
    tableView_heightForRowAtIndexPath: function(tableView, indexPath) {
    return 60
    },
    tableView_didSelectRowAtIndexPath: function(tableView, indexPath) {
    var alertView = require('UIAlertView').alloc().initWithTitle_message_delegate_cancelButtonTitle_otherButtonTitles("Alert",self.dataSource()[indexPath.row()], self, "OK",  null);
    alertView.show()
    },
    alertView_willDismissWithButtonIndex: function(alertView, idx) {
    console.log('click btn ' + alertView.buttonTitleAtIndex(idx).toJS())
    }
    })


 #####  更新频率

我之前看到很多人把使用js和下载js的代码都放在了didFinishLaunchingWithOptions:这个方法。我觉得有所不妥,因为如果这个app用户一直放在手机的后台(比如微信),并且也没出现内存警告的话,这个方法应该一直不会调用。我建议的是:使用js文件的代码放在didFinishLaunchingWithOptions: 而下载js文件的代码放在applicationDidBecomeActive: 因为这个方法在程序启动和后台回到前台时都会调用。并且我建议设置一个间隔时间,根据一些�数据和权衡之后我们采用的是间隔时间设为1小时。 也就是说每次来到这个方法时,先要检测是距离上次发请求的时间间隔是否超过1小时,超过则发请求,否则跳过。

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

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

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

  至此JSPatch在前端设置和使用差不多了。

步骤5:通过请求后台更新项目中demo.js补丁文件来达到动态修复项目Bug的功能。demo.js从后台下载后要加密存储到沙盒中。

#####  demo.js的加密:
    在使用JSPatch时,JS脚本理论上可以调用任意OC方法,权限非常大,若经过HTTP传输时,被中间人攻击篡改js代码,则会造成很大危害。

    鉴于此种情况

        1. 服务器尽量使用https传输
        2. 对传输的代码做好加密和校验

PHP、iOS 使用JSPatch基本与RSA,AES加密: http://www.jianshu.com/p/e6191c9e63c1

About

ios 动态修复bug补丁第三方库JSPatch 使用学习:JSPatch导入、和使用、.js文件传输加解密

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Objective-C 81.1%
  • JavaScript 11.1%
  • Shell 7.8%