iosswiftappdelegatecoordinator-pattern

How to use Coordinator pattern in Xcode 11/iOS13 on UIKit?


I have been trying to learn the Coordinator pattern by creating a new app on Xcode 11.2 using Storyboards as Interface design.
I followed this video by Paul Hudson but I got stuck at minute 12 when code needed to be added to the AppDelegate.swift file. Like it is the app will launch, the first view controller will show but it will not navigate.
What should I change or, better, where should I move the present code to make it work?
Whole project can be found here.
In short the code that in iOS 12 and before was in AppDelegate is this:

var coordinator: MainCoordinator?
var window: UIWindow?

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    let navController = UINavigationController()
    coordinator = MainCoordinator(navigationController: navController)
    coordinator?.start()

    window = UIWindow(frame: UIScreen.main.bounds)
    window?.rootViewController = navController
    window?.makeKeyAndVisible()

    return true
}

I have seen that now window is in SceneDelegate but moving everything there to the sceneDidConnect method is not helping. Can someone enlighten me here?

Thanks!


Solution

  • So a few changes have to be made to be able to implement this pattern. Firstly, you should restore your AppDelegate to it's initial format on creation:

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

    You can remove the var coordinator: MainCoordinator? declaration at the top.

    In SceneDelegate replace the code in the sceneWillConnectToSession function with the following:

    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { 
        guard let windowScene = (scene as? UIWindowScene) else { return }
        let navController = UINavigationController()
        let coordinator = MainCoordinator(navigationController: navController)
        coordinator.start()
    
        let window = UIWindow(windowScene: windowScene)
        window.rootViewController = navController
        self.window = window
        window.makeKeyAndVisible()
    }
    

    The final change is that I removed the weak declaration for MainCoordinator in your view controllers.

    So I just replaced it with var coordinator: MainCoordinator?, and then it worked.

    Reference Article: The Scene Delegate In Xcode 11 And iOS 13