iOS利用RunTime机制添加热补丁

原文链接

http://www.cnblogs.com/machao/p/5198555.html?utm_source=tuicool&utm_medium=referral


ios 由于苹果的审核政策,一旦上线后发现bug是件让人崩溃的事情

不过可以利用oc的runtime机制可以家用JSPatch动态的为工程打热补丁

下载地址:https://github.com/agelessman/JSPatch.git

如果不用cocoapods导入的话,不需要修改,如果拖到工程的,需要改头文件,

例如: #import “abc.h”

在appdelegate中添加类似下边的方法,写一个本地的属性记录补丁的版本号,如果文件存在,再调用

- (void)hotfix {
    
    // 获得应用程序沙盒的Downloads文件夹路径
    
    QKYGuideAccount *guideAccount = [QKYAccountTool guideAccount];
    
    NSArray *arrDownloadPaths =  NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES);
    NSString *loadPathsPath=[arrDownloadPaths objectAtIndex:0];
    NSString *patchPath = [loadPathsPath stringByAppendingPathComponent:[NSString stringWithFormat:@"patch_%@.js",guideAccount.patchVersion.length ? guideAccount.patchVersion : @"0"]];
    NSFileManager *fileManager = [NSFileManager defaultManager];
    BOOL isdir = NO;
    if ([fileManager fileExistsAtPath:patchPath isDirectory:&isdir]) {
        [JPEngine startEngine];
        [JPEngine evaluateScript:[NSString stringWithContentsOfFile:patchPath encoding:NSUTF8StringEncoding error:nil]];
    };
    
    QKYLog(@"Downloads path: %@",patchPath);
}

在控制器中添加下边的方法,目的就是发请求到服务器,获取是否更新,//处理热修复
 
//处理热修复
    self.dataController = [[QKYListDataController alloc] init];
    [self.dataController getIsNeedHotfixResultWithSuccessBlock:^(QKYIsNeedHotfixResult *  _Nonnull success, BOOL last) {
        
        if (success.code.integerValue == 1 && success.newpatch.integerValue == 1) {// 现在补丁
            [self.dataController downloadpatchWithUrl:success.patchurl];
        }
        
        
    } errorMsgBlock:^(NSError * _Nullable error, id  _Nullable msgBody) {
        
    }];
    
    NSDictionary *infoDictionary = [[NSBundle mainBundle] infoDictionary];
    NSString *version            = [infoDictionary objectForKey:@"CFBundleShortVersionString"];
    NSMutableDictionary *dicM = [NSMutableDictionary dictionary];
    [dicM setValue:@"2" forKey:@"comefrom"];
    [dicM setValue:version forKey:@"patchappversion"];
    QKYGuideAccount *guide = [QKYAccountTool guideAccount];
    [dicM setValue:guide.patchVersion.length ? guide.patchVersion : @"0" forKey:@"patchversion"];

需要说明的是这里的dataController 是一个模型,下载补丁的方法封装到了这个模型中

在下载的条件成熟的情况下,下载附件

- (void)downloadpatchWithUrl:(NSString *)url {
    
    if (!url) return;
    
    NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
    
    AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration];
    
    manager.responseSerializer = [AFHTTPResponseSerializer serializer];
    
    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:url]];
    
    NSProgress *downloadProgress = nil;
    
    NSURLSessionDownloadTask *downloadTask = [manager downloadTaskWithRequest:request progress:&downloadProgress destination:^NSURL * _Nonnull(NSURL * _Nonnull targetPath, NSURLResponse * _Nonnull response) {
        
        NSURL *downloadURL = [[NSFileManager defaultManager] URLForDirectory:NSDocumentDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:NO error:nil];
        return [downloadURL URLByAppendingPathComponent:[NSString stringWithFormat:@"patch_%@.js",self.result.patchversion]];
        
    } completionHandler:^(NSURLResponse * _Nonnull response, NSURL * _Nullable filePath, NSError * _Nullable error) {
        
 
        if (error) {
            return ;
        }
        QKYGuideAccount *account = [QKYAccountTool guideAccount];
        account.patchVersion = self.result.patchversion;
        [QKYAccountTool saveGuideAccount:account];
        
        [appDelegate hotfix];
        
        
    }];

    [downloadTask resume];
}

下载成功后保存最新的补丁号到本地属性中,调用JSPatch,让刚下载的代码生效

需要特别说明的是,加载补丁文件,是有顺序的,例如0,1,2 而且补丁文件中使用的是js的代码,

能够帮助我的功能:

1 修复导致崩溃的错误

2 替换原来的方法

3.添加新的方法

4 替换原来的界面

等等,更多功能,有待研究

有问题可以写评论哦,


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值