问题描述
最近有一个应用需要接入 广点通 SDK. 就 SDK 本身接口来说也不多, 结束非常简单, 但是在测试时候发现了 iOS13 系统下, 所有功能一切正常, 但是 iOS12 系统下, 开屏广告不能够正常显示, 并且有以下报错信息:
1
Error Domain=GDTAdErrorDomain Code=4019 "开屏广告 rootViewController 已经 presenting"
解决方法
报错信息看的是一头雾水, 和 Present 有关的话, 再 App 刚刚启动这段时间里一共有 2 个:
- 广点通开屏广告的
ViewController. - 检测用户是否有
快捷口令, 提示用户的UIAlertController.
尝试屏蔽掉 UIAlertController 之后, 开屏广告 能够正常在 iOS12 上面显示了.
此处的解决办法只好再广告展示完成之后再对用户展示提示信息.
原因分析
通过以下一段代码来做一个实验:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor whiteColor];
__weak typeof(self) ws = self;
[[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationDidFinishLaunchingNotification object:nil queue:nil usingBlock:^(NSNotification * _Nonnull note) {
[ws present:[UIColor redColor]];
[ws present:[UIColor yellowColor]];
}];
}
/// 模态一个视图控制器
/// @param color 控制器视图背景颜色
- (void)present:(UIColor *)color {
UIViewController *vc = [[UIViewController alloc] init];
vc.view.backgroundColor = color;
__weak typeof(vc) wv = vc;
[self presentViewController:vc animated:YES completion:^{
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[wv dismissViewControllerAnimated:YES completion:nil];
});
}];
}
测试对比
- 当运行在
iOS12系统上时候, 有如下警告信息:Warning: Attempt to present <UIViewController: 0x10260ad80> on <ViewController: 0x102608870> whose view is not in the window hierarchy! - 当运行在
iOS13系统上时候, 有如下警告信息:Warning: Attempt to present <UIViewController: 0x104e0b640> on <ViewController: 0x104e045c0> which is already presenting <UIViewController: 0x104e09b50>
以上 2 种情况的观测结果是一致的, 都只模态出了 红色 背景的视图控制器, 仅仅是 警告信息不同.
而造成 警告信息不同 这一结果的就是在 iOS13 之后, UIViewController 的 modalPresentationStyle 属性的默认值变为了 UIModalPresentationAutomatic(立体感的卡片效果), 在此之前默认值是 UIModalPresentationFullScreen (全屏视图覆盖效果).
当把 modalPresentationStyle 设为 UIModalPresentationFullScreen 之后, iOS13 系统种也会跟 iOS12 报同样的错误, 也就是同样会出现 开屏广告无法正常展示 的问题.
结论
虽然知道了造成 iOS12 和 iOS13 效果不同的原因, 但是并未了解到两种警告的意义在细节上有什么不同.
第一种警告如果是因为发起 Present 的 Controller.view 已经不在当前 Window 的层次结构中 (模态起来).