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

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

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

右键点击生成的动态库,选择Show in Finder,把我们生成的动态库拷贝到桌面,待放入APP沙盒使用。
2、APP使用动态库
我们创建一个简单的APP,由一个NavigationController和一个UIViewController组成,放上一个按钮,用于push出动态库里面的UIViewController,如果push成功则代表加载动态库成功。热更新一般是需要从服务器下载动态库放沙盒替换进行更新,此处测试则人工手动放入,省略了从服务器下载动态库的过程。界面如下:

在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
网友评论