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)
)

你可能感兴趣的:(iOS开发 MangoFix结合码云储存补丁文件实现热更新)