Swift
iOS
AppDelegate
ViewController
Programming

Opening view controller from app delegate using swift

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

Introduction

Opening a view controller from AppDelegate means creating the app window, assigning a root view controller, and making that window visible. This was a common pattern before scene-based life cycle APIs became standard, and it still matters for older projects or projects that manage startup routing manually. In modern iOS apps, the same idea often belongs in SceneDelegate instead.

What AppDelegate Is Really Responsible For

AppDelegate handles application-wide events such as launch, notifications, and app state transitions. In older UIKit life cycle setups, it was also the place where the initial UIWindow and root view controller were configured.

If you are not using the default storyboard entry point, or you want runtime logic to decide what screen appears first, setting the root controller in code is the right approach.

Typical reasons include:

  • showing login or main flow depending on session state
  • bypassing the storyboard's initial controller
  • injecting dependencies at startup
  • supporting older single-window app structure

Set the Root View Controller Programmatically

In a pre-scene life cycle app, you can create the window and assign a root controller in application(_:didFinishLaunchingWithOptions:).

swift
1import UIKit
2
3@main
4class AppDelegate: UIResponder, UIApplicationDelegate {
5    var window: UIWindow?
6
7    func application(
8        _ application: UIApplication,
9        didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
10    ) -> Bool {
11        let window = UIWindow(frame: UIScreen.main.bounds)
12        let rootViewController = HomeViewController()
13        let navigationController = UINavigationController(rootViewController: rootViewController)
14
15        window.rootViewController = navigationController
16        window.makeKeyAndVisible()
17        self.window = window
18
19        return true
20    }
21}

This does not “present” a view controller in the modal sense. It installs the first controller for the app's window.

Load the Controller from a Storyboard When Needed

If the screen lives in a storyboard, instantiate it first and then assign it as the root.

swift
1import UIKit
2
3@main
4class AppDelegate: UIResponder, UIApplicationDelegate {
5    var window: UIWindow?
6
7    func application(
8        _ application: UIApplication,
9        didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
10    ) -> Bool {
11        let storyboard = UIStoryboard(name: "Main", bundle: nil)
12        let window = UIWindow(frame: UIScreen.main.bounds)
13        let controller = storyboard.instantiateViewController(withIdentifier: "LoginViewController")
14
15        window.rootViewController = controller
16        window.makeKeyAndVisible()
17        self.window = window
18
19        return true
20    }
21}

This pattern is useful when you still want storyboard-based UI but need code to choose the launch screen.

Prefer Root Assignment Over Modal Presentation at Launch

At app startup, the cleanest approach is usually to choose the right root controller rather than trying to call present(_:animated:) from nowhere. Modal presentation needs an already visible presenter. During launch, the window's root controller is the actual foundation of the UI.

If your goal is to switch flows after login or logout, update window?.rootViewController instead of stacking modal screens on top of a launch controller that should no longer matter.

In Modern Apps, This Often Belongs in SceneDelegate

Since iOS 13, scene-based apps usually move window setup to SceneDelegate. The same startup logic still applies, but the ownership shifts from the application delegate to the scene.

swift
1import UIKit
2
3class SceneDelegate: UIResponder, UIWindowSceneDelegate {
4    var window: UIWindow?
5
6    func scene(
7        _ scene: UIScene,
8        willConnectTo session: UISceneSession,
9        options connectionOptions: UIScene.ConnectionOptions
10    ) {
11        guard let windowScene = scene as? UIWindowScene else { return }
12
13        let window = UIWindow(windowScene: windowScene)
14        let controller = UINavigationController(rootViewController: HomeViewController())
15
16        window.rootViewController = controller
17        window.makeKeyAndVisible()
18        self.window = window
19    }
20}

So when someone asks how to open a view controller from AppDelegate, the correct answer may be “only if your project still uses the old single-window life cycle.”

Use Startup Routing for Real Decisions

One practical use for programmatic startup is session-aware routing. For example, show a login controller if no authenticated user exists, otherwise show the main app flow.

That decision can be expressed cleanly in one place during startup instead of being scattered across several launch screens.

The architecture benefit is often bigger than the UI benefit: it gives the app one clear entry point for state-based routing.

Common Pitfalls

The most common mistake is trying to present a controller modally from AppDelegate without setting up a visible window and root controller first.

Another mistake is copying AppDelegate startup code into a scene-based app where the real window ownership now lives in SceneDelegate.

Developers also forget to retain the UIWindow in a property. If the window is not stored, it can disappear immediately.

Summary

  • In older UIKit apps, opening a screen from AppDelegate means creating a window and assigning its root view controller.
  • If the controller comes from a storyboard, instantiate it and set it as the window root.
  • At launch, root-controller assignment is usually better than modal presentation.
  • In scene-based apps, the equivalent logic usually belongs in SceneDelegate.
  • Programmatic startup is most useful when app state determines which flow should appear first.

Related reading
Free course
Beginner
7 lessons
2 hours
Tackling System Design Interview Problems

A short course that equips you with the skills to approach system design interviews methodically.

Start the free course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.