iOS动态库热更新

作者: iOS_tree | 来源:发表于2018-12-04 10:01 被阅读911次

出于苹果的审核机制,现在极少有使用热更新开发的APP,在项目中也使用极少。出于对热更新的好奇,写了一个热更新的demo。
如果你的项目不需要上架审核则可以使用热更新来更新APP。
苹果的热更新方案有许多种,这里使用的是苹果原始的Dynamic Library热更新。
动态库更新主要分为两部分:1、创建动态库;2、APP加载动态库。

1、创建动态库

创建时选择Cocoa Toucn Framework即可。


image.png

修改编译参数,编译文件类型为Dynamic Library即可


image.png
然后即可创建自己的代码文件了。我们创建一个UIViewController,设置背景颜色,然后run则生成动态库framework,点击run时选择模拟器即可,iOS10之后真机已经不能把动态库放入沙盒进行动态加载了,所以我们进行模拟器运行,经测试,模拟器无此限制。
image.png

右键点击生成的动态库,选择Show in Finder,把我们生成的动态库拷贝到桌面,待放入APP沙盒使用。

2、APP使用动态库

我们创建一个简单的APP,由一个NavigationController和一个UIViewController组成,放上一个按钮,用于push出动态库里面的UIViewController,如果push成功则代表加载动态库成功。热更新一般是需要从服务器下载动态库放沙盒替换进行更新,此处测试则人工手动放入,省略了从服务器下载动态库的过程。界面如下:


image.png

在UIViewController里面的viewDidLoad代码如下:

- (void)viewDidLoad {
    [super viewDidLoad];
    
    //iOS 10后真机不可用,模拟器可用
    NSString *libPath = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES).lastObject;
    NSLog(@"%@",libPath);
    
    libPath = [NSString stringWithFormat:@"%@/%@",libPath,@"ESCViewControllerDynamic.framework"];
    
    self.libPath = libPath;
}

我们把动态库放到Library文件夹下面。
在按钮的点击方法的代码如下:

 BOOL exists = [[NSFileManager defaultManager] fileExistsAtPath:self.libPath];
    if (exists == NO) {
        NSLog(@"动态库不存在");
        return;
    }
    
    NSBundle *libBundle = [NSBundle bundleWithPath:self.libPath];
    if (libBundle == nil) {
        NSLog(@"生成bundle失败");
        return;
    }
    
    self.boundle = libBundle;
    
    BOOL loadResult = [libBundle load];
    if (loadResult == NO) {
        NSLog(@"已经load或者加载失败");
    }else {
        NSLog(@"加载成功");
    }
    Class vClass = [libBundle classNamed:@"ESCViewController"];
    
    if (vClass == nil) {
        NSLog(@"加载类失败");
    }else{
        UIViewController *viewController = [[vClass alloc] init];
        if (viewController) {
            [self.navigationController pushViewController:viewController animated:YES];
        }
    }

在APP启动后,我们点击按钮是push不成功的,因为此时沙盒里面没有动态库的。
我们把第一步生成的放在桌面的动态库拷贝到APP沙盒中的Library文件夹中,然后再点击按钮,则成功push出动态库里面的UIViewController,此时代表加载动态库成功。
这个方法为iOS原生的热更新方案实现方法,由于在iOS10之后的系统已经禁止将动态库放在沙盒中加载,如果需要使用热更新,此方法则不可用,可以在模拟器上测试使用,说不定以后苹果开放了热更新就又可以用了。在现有阶段除了系统提供的动态库的热更新,其他也有许多方案,但苹果审核一般比较难以通过,所以不建议使用。
欢迎讨论,附上demo地址:
https://github.com/XMSECODE/ESCDynamicUpdateDemo

相关文章

网友评论

    本文标题:iOS动态库热更新

    本文链接:https://www.haomeiwen.com/subject/kimhcqtx.html