AppDelegate and SceneDelegate when supporting iOS 12 and 13

一世执手 提交于 2020-04-27 04:37:52

问题


I need to support iOS 12 and iOS 13.

Should I be duplicating code between AppDelegate and SceneDelegate?

For example:

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
}

and

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
}

If I don't do this, in 1 version I end up with a black screen, but if I do and print in the viewDidLoad method of HomeViewController I can see it is called twice.

I update my didFinishLaunchingWithOptions and I can see in iOS13 it is still called twice.

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
}

回答1:


You do need to duplicate the code but you need to make sure it runs only on the correct system. In iOS 13 you don’t want that application delegate didFinishLaunching body code to run, so use an availability check to prevent it. In the same way, use availability to hide the window scene stuff from iOS 12.

Here's the basic sketch of a solution that runs correctly on both iOS 12 and 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
    }
}

Note that dealing with other duplicates, such as the application activating, is much simpler because if you support window scenes the application delegate method won't be called on iOS 12. So the problem is confined to this one situation, namely where you have window / root view controller manipulations to perform at launch (e.g. no storyboard).




回答2:


Xcode 11.* and Swift 5.*

Follow the steps given below after that your code will work fine for both iOS 12 and iOS 13 -

  1. Remove the scene manifest from info.plist file
  2. Remove scene delegate
  3. Add window property inside the AppDelegate
  4. Remove all the methods(2 methods mostly) related to the scene from AppDelegate

Hope this will work for someone. Happy Coding 🤓



来源:https://stackoverflow.com/questions/58405393/appdelegate-and-scenedelegate-when-supporting-ios-12-and-13

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!