Creating a TabBarController in AppDelegate

Hi everyone, wish you a happy New Year 2020 !


What could be wrong in that methode ? I'm wonder why "window" stay nil.


import UIKit

@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.
        if let tabBarController = window?.rootViewController as? UITabBarController {
            let storyboard = UIStoryboard(name: "Main", bundle: nil)
            let vc = storyboard.instantiateViewController(withIdentifier: "NavController")
            vc.tabBarItem = UITabBarItem(tabBarSystemItem: .topRated, tag: 1)
            tabBarController.viewControllers?.append(vc)
        }
        
        return true
    }


The lines #12 to #15 are never used !?

https://www.judogokyo.com/ftp/P7MainStoryboard.png

Thanks a lot

You mean lines 11 to 15 I guess ?


window?.rootViewController is nil, because window is nil.

See here:

https://stackoverflow.com/questions/34159160/why-is-appdelegate-swift-window-an-optional


In some cases (for instance if you define your App as a Master Detail App), system handles initialization by itself.


In other cases, the template for the app does not even contain a window in AppDelegate. That's the case if you have a scene delegate


So, if you have SceneDelegate, remove the window declaration in AppDelegate, remove the code you added in didFinishLaunching and put it in Scenedelegate (you have a window declared here).

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 }
       
        print(window!)  // Let's take the risk to unwrap !
        print(window!.rootViewController!)
       
        if let tabBarController = window?.rootViewController as? UITabBarController {
            let storyboard = UIStoryboard(name: "Main", bundle: nil)
            print("I passed here in willConnectTo")
            let vc = storyboard.instantiateViewController(withIdentifier: "NavController")
            vc.tabBarItem = UITabBarItem(tabBarSystemItem: .topRated, tag: 1)
            tabBarController.viewControllers?.append(vc)
        }
    }

// Other SceneDelegate func here 
}

You will get on console:

<UIWindow: 0x7fc53640c110; frame = (0 0; 414 896); hidden = YES; gestureRecognizers = <NSArray: 0x6000030b90e0>; layer = <UIWindowLayer: 0x600003eaad00>>

<UITabBarController: 0x7fc536822200>

I passed here in willConnectTo



Good tutorial here:

h ttps://learnappmaking.com/scene-delegate-app-delegate-xcode-11-ios-13/

Did it work ?


If not, where is the other problem ?

Creating a TabBarController in AppDelegate
 
 
Q