0%

iOS 13修改启动图未生效

反馈请联系hertz@hertzwang.com,谢谢

前言:由于业务要求需要更新应用启动图,拿到新图时分分钟替换完事儿,经测试在iOS 13系统上未生效

问题排查

启动图使用 LaunchScreen.storyboard 的方式,在查阅资料与实践后得出结论:

  • 系统会根据LaunchScreen.stroboard的内容生成屏幕快照(@2x和@3x)
  • 快照存放在Library/SplashBoard/Snapshots
  • 第次运行时都会生成新的快照图片,根据屏幕倍数显示相应的快照图片
  • 在 iOS 13 系统中,更新图片名称、内容,并删除快照图片缓存后,下次启动时启动图才更新

也就是说在 iOS 13 上,更新启动图需要改图片名称、删除快照图片缓存,在下次启动时才生效!!!

解决方案

在 iOS 13 上冷启动时校验缓存图片与当前图片是否一致,若缓存图片不存在或图片不一致则删除快照缓存并更新缓存图片,图片一致时不处理

代码示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
+ (void)cleanSplashBoard {
float systemVersion = [WM_CURRENT_SYSTEM_VERSION floatValue];
if (systemVersion >= 13.0 && systemVersion < 14.0) {
NSString *documentsPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject;
NSString *folderPath = [documentsPath stringByAppendingPathComponent:@"Data"];
NSString *imageCachePath = [folderPath stringByAppendingPathComponent:@"SplashBoard"]; // ~/Documents/Data/SplashBoard
// 准备
BOOL isDirectory = YES;
if (![[NSFileManager defaultManager] fileExistsAtPath:folderPath isDirectory:&isDirectory]) {
[[NSFileManager defaultManager] createDirectoryAtPath:folderPath withIntermediateDirectories:YES attributes:nil error:nil];
}
NSError *error = nil;
// 1.获取Images.xcassets中启动图
UIStoryboard *sb = [UIStoryboard storyboardWithName:@"LaunchScreen" bundle:nil];
NSAssert(sb != nil, @"未找到 LaunchScreen.storyboard 文件");
UIViewController *vc = [sb instantiateInitialViewController];
UIImage *currentImage = nil;
for (UIView *subview in vc.view.subviews) {
if ([subview isKindOfClass:[UIImageView class]]) {
currentImage = ((UIImageView *)subview).image;
break;
}
}
if (currentImage == nil) {
NSAssert(currentImage != nil, @"LaunchScreen.storyboard 中缺少 ImageView");
return;
}
NSData *currentData = UIImagePNGRepresentation(currentImage);
// 2.获取缓存的启动图
NSData *cachedData = [[NSData alloc] initWithContentsOfFile:imageCachePath];
if (cachedData && [cachedData isEqualToData:currentData]) {
return;
}
[[NSFileManager defaultManager] removeItemAtPath:[NSHomeDirectory() stringByAppendingString:@"/Library/SplashBoard"] error:nil];
[currentData writeToFile:imageCachePath atomically:YES];
}
}