iOS开发 MangoFix结合码云储存补丁文件实现热更新

选择技术实现方案

近段时间,由于公司要求需要增加热更新或热修复功能,这个开发需求让我有点头疼。记忆中苹果公司已于2017年3月禁止了JSPatch那种方式的热更新,我只好放弃JSPatch这种方案。网上找了一圈,只有TTPatch和MangoFix这两个框架可行,但这两个框架目前都不支持swift语言开发的项目。由于我手上的公司项目代码还是OC开发的项目,不影响使用这两个框架。TTPatch是JSPatch的简化版,原理与JSPatch相似。MangoFix是DSL(即领域专用语言)开发的,性能比TTPatch高出好几倍。对比这两个框架后,我选择了MangoFix,其实最主要的原因是MangoFix可以无感进行修复代码,用户不用下载补丁文件操作,只需要配置更新文件的远程地址将更新文件保存在本地即可。另外,据MangoFix的作者说,MangoFix2.0版本将支持swift语言,我们一起期待吧!

更新于12月1日

目前已经从MangoFix升级到OCRunner,OCRunner可以支持方法以dynamic @objc开头的Swift文件热修复。相比MangoFix支持的方法更多了。参考以下链接文档

https://github.com/SilverFruity/OCRunner/blob/master/README-CN.md

码云储存补丁配置远程地址

首先,新建一个码云仓库的公开开源项目,记得不要建私有项目,这样会导致访问不了文件的问题出现。
然后,将mg后缀的补丁文件上传上去即可。
最后,我们需要知道补丁文件的远程地址。怎么从码云那里获取到远程地址呢?可以从以下截图获得


info.png

MangoFix使用方法

MangoFix的具体使用请参照GitHub上的说明,请点击查看(Mango/README-CN.md at master · YPLiang19/Mango (github.com)
)。
其实最重要的是将MangoFix打包下载下来,打开MangoFixDemo文件夹里面的Demo。想使用远程地址替换本地的更新需要将下面代码进行设置:

#pragma mark - 热修复
- (BOOL)encryptPlainScirptToDocument{
    NSError *outErr = nil;
    BOOL writeResult = NO;

    //本地
//    NSURL *scriptUrl = [[NSBundle mainBundle] URLForResource:@"xxxPatch" withExtension:@"mg"];
    
    //远程
   NSDictionary *info= [[NSBundle mainBundle] infoDictionary];
   NSString *BundleVersion = info[@"CFBundleShortVersionString"];
   NSString *pathStr = [NSString stringWithFormat:@"https://gitee.com/xxx/xx-patch/raw/master/xxxPatch%@.mg",BundleVersion];
#ifdef DEBUG
    pathStr = @"https://gitee.com/xxx/xx-patch/raw/master/xxxPatchTest.mg";
#else

#endif

    NSURL *scriptUrl = [NSURL URLWithString:pathStr];
    NSString *plainScriptString = [NSString stringWithContentsOfURL:scriptUrl encoding:NSUTF8StringEncoding error:&outErr];
    if (outErr) goto err;

    {
        NSURL *publicKeyUrl = [[NSBundle mainBundle] URLForResource:@"public_key.txt" withExtension:nil];
        NSString *publicKey = [NSString stringWithContentsOfURL:publicKeyUrl encoding:NSUTF8StringEncoding error:&outErr];
        if (outErr) goto err;
        NSString *encryptedScriptString = [MFRSA encryptString:plainScriptString publicKey:publicKey];

        NSString * encryptedPath= [(NSString *)[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject] stringByAppendingPathComponent:@"encrypted_xxxPatch.mg"];
        NSFileManager *fileManager = [NSFileManager defaultManager];
        if (![fileManager fileExistsAtPath:encryptedPath]) {
            [fileManager createFileAtPath:encryptedPath contents:nil attributes:nil];
        }
        writeResult = [encryptedScriptString writeToFile:encryptedPath atomically:YES encoding:NSUTF8StringEncoding error:&outErr];
    }
err:
    if (outErr) NSLog(@"%@",outErr);
    return writeResult;
}

总结

OK,以上几步完成基本就可以实现热更新了,具体的测试案例可以参照MangoFixDemo里面的案例。

参考资料如下:

[MangoFix中文资料](Mango/README-CN.md at master · YPLiang19/Mango (github.com)

[iOS热更新方案](iOS 现在的 “热修复/热更新” - 简书 (jianshu.com)
)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 我是黑夜里大雨纷飞的人啊 1 “又到一年六月,有人笑有人哭,有人欢乐有人忧愁,有人惊喜有人失落,有的觉得收获满满有...
    陌忘宇阅读 8,607评论 28 53
  • 信任包括信任自己和信任他人 很多时候,很多事情,失败、遗憾、错过,源于不自信,不信任他人 觉得自己做不成,别人做不...
    吴氵晃阅读 6,231评论 4 8
  • 步骤:发微博01-导航栏内容 -> 发微博02-自定义TextView -> 发微博03-完善TextView和...
    dibadalu阅读 3,189评论 1 3
  • 回这一趟老家,心里多了两个疙瘩。第一是堂姐现在谈了一个有妇之夫,在她的语言中感觉,她不打算跟他有太长远的计划,这让...
    安九阅读 3,545评论 2 4