Set rootViewController iOS 13

For anyone looking to create a couple of extensions to change the root view controller and need to support both delegate types (UISceneDelegate and AppDelegate), here's a couple:

    extension UIViewController {
        var appDelegate: AppDelegate {
        return UIApplication.shared.delegate as! AppDelegate
    }
    
    var sceneDelegate: SceneDelegate? {
        guard let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene,
            let delegate = windowScene.delegate as? SceneDelegate else { return nil }
         return delegate
    }
}

And if you're in need of an extension to reach the UIWindow from a ViewController with iOS12 and iOS13 Support:

extension UIViewController {
    
    var window: UIWindow? {
        if #available(iOS 13, *) {
            guard let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene,
                let delegate = windowScene.delegate as? SceneDelegate, let window = delegate.window else { return nil }
                   return window
        }
        
        guard let delegate = UIApplication.shared.delegate as? AppDelegate, let window = delegate.window else { return nil }
        return window
    }
}

It is available in SceneDelegate.swift file in your project

It will have delegate method :

func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions)

Example

func scene(_ scene: UIScene, willConnectTo session: UISceneSession,
 options connectionOptions: UIScene.ConnectionOptions) {


if let windowScene = scene as? UIWindowScene {

    self.window = UIWindow(windowScene: windowScene) 

    let initialViewController = 
        storyboard.instantiateViewController(withIdentifier: "FirstViewController")            
        self.window!.rootViewController = initialViewController
        self.window!.makeKeyAndVisible()
    }

}

This is because AppDelegate doesn't have window property anymore. Now you must use SceneDelegate's scene(_:willConnectTo:options:) method to change root view controller. Like shown in this example:

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

        // Instantiate UIWindow with scene
        let window = UIWindow(windowScene: scene)
        // Assign window to SceneDelegate window property
        self.window = window
        // Set initial view controller from Main storyboard as root view controller of UIWindow
        self.window?.rootViewController = UIStoryboard(name: "Main", bundle: nil).instantiateInitialViewController()
        // Present window to screen
        self.window?.makeKeyAndVisible()
    }

In viewDidAppear you can set root:-

  override func viewDidAppear(_ animated: Bool) {
            print(self.view.window)
            let vc = self.storyboard?.instantiateViewController(identifier: "SecondViewController") as? SecondViewController
            self.view.window?.rootViewController = vc
        }