场景
Xcode 11 建新工程默认会创建通过 UIScene 管理多个 UIWindow 的应用,工程中除了 AppDelegate 外还会有一个 SceneDelegate,这是为了实现iPadOS支持多窗口的结果。AppDelegate.h不再有window属性,window属性被定义在了SceneDelegate.h中,AppDelegate中有新增的关于scene的代理方法,SceneDelegate中也有相应的代理方法。因此,当我们用Xcode11针对不同版本的iOS开发应用时,就要做一些适配。
不支持SceneDelegate
如果项目不支持iPad可以直接删除这个选项;
1.去Info.plist
找到Application Scene M anifest
这个选项直接删除
2.然后在AppDelegate
添加一个window,之后按照正常的项目启动配置就可以
支持SceneDelegate
默认在info.plist中进行了配置, 不用实现该方法也没有关系。如果没有配置就需要实现这个方法并返回一个UISceneConfiguration
对象。
配置参数中Application Session Role 是个数组,每一项有三个参数:
Configuration Name
: 当前配置的名字
Delegate Class Name
: 与哪个Scene代理对象关联
StoryBoard name
: 这个Scene使用的哪个storyboard(没有StoryBoard可以删除该选项)
注意: 代理方法中调用的是配置名为Default Configuration的Scene,则系统就会自动去调用SceneDelegate这个类。这样SceneDelegate和AppDelegate产生了关联。
代码配置
1.在AppDelegate里添加兼容代码;兼容iOS13的多窗口可以使用Extension进行添加@available(iOS 13.0, *)
进行单独适配的扩展
// 可以删除Appdelete的SceneDelegate默认配置代码
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
if #available(iOS 13.0, *) {} else {
window = UIWindow(frame: UIScreen.main.bounds)
window?.rootViewController = ViewController()
window?.backgroundColor = .white
window?.makeKeyAndVisible()
}
return true
}
2.在SceneDelegate里指定主窗口
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
guard let windowScene = (scene as? UIWindowScene) else { return }
window = UIWindow(windowScene: windowScene)
window?.frame = UIScreen.main.bounds
window?.rootViewController = ViewController()
window?.backgroundColor = .white
window?.makeKeyAndVisible()
}
IDFA弹框授权
适配了SceneDelgate方法,Appdelegate的applicationDidBecomeActive
就会不执行,这个时候就需要把请求授权的方法放到适配了SceneDelgate的sceneDidBecomeActive
方法中才会执行
func sceneDidBecomeActive(_ scene: UIScene) {
// 有时候可能无法弹出授权窗口,这里延迟1s获取
if #available(iOS 14.0, *) {
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
ATTrackingManager.requestTrackingAuthorization { status in
}
}
} else {
}
}