Search code examples
iosswiftviewcontrollerios13viewdidload

ViewDidLoad gets called twice iOS 13+


I am developing an app for iOS 12+ and the fact that iOS 13 requires a SceneDelegate is causing me some problems when displaying the first ViewController programmatically, as I don't use storyboards.

In the AppDelegate.swift I use this code to present the ViewController for devices that don't have iOS 13 installed yet:

var window: UIWindow?

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    FirebaseApp.configure()
    Database.database().isPersistenceEnabled = true

    IQKeyboardManager.shared.enable = true
    window = UIWindow()
    window?.rootViewController = ViewController()
    window?.makeKeyAndVisible()
    window?.backgroundColor = .main
    window?.rootViewController = UINavigationController(rootViewController: ViewController())
    return true
}

This works properly for those devices; in the SceneDelegate.swift tho, I have to put the following code to present the first ViewController:

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 winScene = (scene as? UIWindowScene) else { return }

    window = UIWindow(windowScene: winScene)
    window?.backgroundColor = .main
    window?.makeKeyAndVisible()
    window?.rootViewController = UINavigationController(rootViewController: ViewController())
}

This works exactly as I expected for the <13.0 iOS versions, as I marked the whole SceneDelegate.swift as available in iOS 13 only, but when I try to run this code on a 13+ iOS version, the ViewDidLoad function of my ViewController gets called twice, because I am technically instantiating it twice. I tried commenting out the code in the AppDelegate.swift, but that won't allow my app to be used in <13.0 iOS versions, and then I tried commenting out the code in the SceneDelegate.swift, but that won't allow my app to be used in 13+ iOS versions.

Is there a way to allow some piece of code to be run only In versions below 13.0? This question is not related to Nibs, xibs or any other problem mentioned in other questions about the ViewDidLoad running twice, please don't mark this as a duplicated of those ones, as it's not.

Thank you, NicopDev


Solution

  • With ios 13 don't do anything inside didFinishLaunchingWithOptions Try

     if #available(iOS 13.0, *) { }
      else {
        window = UIWindow()
        window?.rootViewController = ViewController()
        window?.makeKeyAndVisible()
        window?.backgroundColor = .main
        window?.rootViewController = UINavigationController(rootViewController: ViewController())
     }
    

    Also you need to comment either

    window?.rootViewController = ViewController()
    

    or

    window?.rootViewController = UINavigationController(rootViewController: ViewController())