在XCode11 之后,在我們新建工程的時(shí)候發(fā)現(xiàn)多了一個(gè)新增文件 SceneDelegate.swift
憨颠,然后我們?nèi)タ聪逻@個(gè)文件到底是干什么用的WWDC2019:Optimizing App Launch在iOS 13之前,APP的生命周期和UI生命周期都是交由AppDelegate來(lái)處理的恬汁,在iOS 13以前谤逼,處理生命周期是下面這樣的。
這種模式是基于只有一個(gè)進(jìn)程時(shí)適用戈盈,因?yàn)閕OS一直以來(lái)都是一個(gè)進(jìn)程運(yùn)行時(shí)只有一個(gè)用戶(hù)界面奠衔。在iOS 13之后,其實(shí)是為了iPadOS的多窗口支持塘娶,它可以高效的把應(yīng)用委托工作分成兩部分归斤。
所以我們看到的是這樣承接了業(yè)務(wù):
// MARK: UISceneSession Lifecycle
func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
// Called when a new scene session is being created.
// Use this method to select a configuration to create the new scene with.
return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
}
func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) {
// Called when the user discards a scene session.
// If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
// Use this method to release any resources that were specific to the discarded scenes, as they will not return.
}
這里是通過(guò)了func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration
把內(nèi)容連接到了SceneDelegate
如下:
var window: UIWindow?
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
// Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
// If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
// This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
guard let _ = (scene as? UIWindowScene) else { return }
}
但是,在很多情況下我們并不需要直接使用iOS 13這么高的版本血柳,并且開(kāi)發(fā)的應(yīng)用程序也沒(méi)有兼容iPadOS(很多時(shí)候官册,iPadOS版本的還是需要另外做個(gè)版本來(lái)適配),所以這里提出了兩個(gè)方案來(lái)進(jìn)行適配
1难捌、添加版本判別運(yùn)行代碼@available
在使用 @available(iOS 13.0, *)進(jìn)行判斷膝宁,如果系統(tǒng)沒(méi)到達(dá)13.0的話(huà)就不啟用該段代碼鸦难。
@available(iOS 13.0, *)
func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
// Called when a new scene session is being created.
// Use this method to select a configuration to create the new scene with.
return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
}
@available(iOS 13.0, *)
func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) {
// Called when the user discards a scene session.
// If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
// Use this method to release any resources that were specific to the discarded scenes, as they will not return.
}
不過(guò),還需要在AppDelegate上添加一個(gè)window才可以保證正常運(yùn)行
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
return true
}
至于SceneDeleagte
上也需要改成只有13.0以后才啟用
import UIKit
@available(iOS 13.0, *)
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
// Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
// If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
// This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
guard let _ = (scene as? UIWindowScene) else { return }
}
func sceneDidDisconnect(_ scene: UIScene) {
// Called as the scene is being released by the system.
// This occurs shortly after the scene enters the background, or when its session is discarded.
// Release any resources associated with this scene that can be re-created the next time the scene connects.
// The scene may re-connect later, as its session was not neccessarily discarded (see `application:didDiscardSceneSessions` instead).
}
2员淫、去掉SceneDelegate相關(guān)內(nèi)容
這是基于不需要使用多窗口支持而提出的解決方案合蔽,首先,需要去掉info.plist 的Application Scene Manifest選項(xiàng)介返,然后對(duì)應(yīng)的SceneDelegate刪除掉拴事。
然后把對(duì)應(yīng)的代碼內(nèi)容也注釋掉或者刪掉對(duì)應(yīng)的內(nèi)容,然后寫(xiě)上對(duì)應(yīng)的生命周期圣蝎,如下:
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
return true
}
func applicationWillResignActive(_ application: UIApplication) {
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
}
func applicationDidEnterBackground(_ application: UIApplication) {
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}
func applicationWillEnterForeground(_ application: UIApplication) {
// Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
}
func applicationDidBecomeActive(_ application: UIApplication) {
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}
func applicationWillTerminate(_ application: UIApplication) {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}
// // MARK: UISceneSession Lifecycle
//
// func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
// // Called when a new scene session is being created.
// // Use this method to select a configuration to create the new scene with.
// return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
// }
//
// func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) {
// // Called when the user discards a scene session.
// // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
// // Use this method to release any resources that were specific to the discarded scenes, as they will not return.
// }
}