一尘不染

支持iOS 12和13时的AppDelegate和SceneDelegate

swift

我需要支持iOS 12和iOS 13。

我应该在AppDelegate和之间复制代码SceneDelegate吗?

例如:

func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
    guard let windowScene = (scene as? UIWindowScene) else { return }
    let window = UIWindow(windowScene: windowScene)

    window.rootViewController = HomeViewController()
    window.makeKeyAndVisible()

    self.window = window
}

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    let window = UIWindow(frame: UIScreen.main.bounds)
    window.rootViewController = HomeViewController()
    window.makeKeyAndVisible()

    self.window = window

    return true
}

如果我不这样做,则在1个版本中,我最终会出现黑屏,但是如果我这样做并以的viewDidLoad方式打印,则HomeViewController可以看到它被称为两次。

我进行了更新didFinishLaunchingWithOptions,可以看到iOS13它仍然被调用了两次。

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

    guard #available(iOS 12, *) else { return true }

    let window = UIWindow(frame: UIScreen.main.bounds)
    window.rootViewController = HomeViewController()
    window.makeKeyAndVisible()

    self.window = window

    return true
}

阅读 701

收藏
2020-07-07

共1个答案

一尘不染

您确实需要复制代码,但需要确保它仅在正确的系统上运行。在iOS
13中,您不希望该应用程序委托didFinishLaunching主体代码运行,因此请使用可用性检查来阻止它。以相同的方式,使用可用性在iOS
12中隐藏窗口场景内容。

这是可以在iOS 12和iOS 13上正常运行的解决方案的基本示意图:

AppDelegate.Swift

import UIKit
@UIApplicationMain
class AppDelegate : UIResponder, UIApplicationDelegate {
    var window : UIWindow?
    func application(_ application: UIApplication,
        didFinishLaunchingWithOptions 
        launchOptions: [UIApplication.LaunchOptionsKey : Any]?)
        -> Bool {
            if #available(iOS 13, *) {
                // do only pure app launch stuff, not interface stuff
            } else {
                self.window = UIWindow()
                let vc = ViewController()
                self.window!.rootViewController = vc
                self.window!.makeKeyAndVisible()
                self.window!.backgroundColor = .red
            }
            return true
    }
}

SceneDelegate.swift

import UIKit
@available(iOS 13.0, *)
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
    var window : UIWindow?
    func scene(_ scene: UIScene,
        willConnectTo session: UISceneSession,
        options connectionOptions: UIScene.ConnectionOptions) {
            if let windowScene = scene as? UIWindowScene {
                self.window = UIWindow(windowScene: windowScene) 
                let vc = ViewController()                      
                self.window!.rootViewController = vc             
                self.window!.makeKeyAndVisible()                 
                self.window!.backgroundColor = .red
            }
    }
}

ViewController.swift

import UIKit
class ViewController : UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        print("view did load")
        self.view.backgroundColor = .green
    }
}

请注意,处理其他重复项(例如,激活应用程序)要简单得多,因为如果您支持窗口场景,则不会在iOS
12上调用应用程序委托方法。因此,问题仅限于这种情况,即您拥有窗口/根视图控制器操纵以在启动时执行(例如,没有故事板)。

2020-07-07