Opening view controller from app delegate using swift

I am trying to create a push notification which determines which view to open according to information obtained from the push.

I have managed to get the information from the push, but I am now struggling to get the view to open

Looking at other stack overflow questions I have the following currently:

App Delegate Did finish loading:

     //Extract the notification data
    if let notificationPayload = launchOptions?[UIApplicationLaunchOptionsRemoteNotificationKey] as? NSDictionary {
        // Get which page to open
        let viewload = notificationPayload["view"] as? NSString
        let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil)
        //Load correct view
        if viewload == "circles" {

            var viewController = self.window?.rootViewController?.storyboard?.instantiateViewControllerWithIdentifier("Circles") as! UIViewController
            self.window?.rootViewController = viewController

                        }
    }

Currently this is failing on the var ViewController = self... line.


You have to set ViewController StoryBoardId property as below image.

enter image description here

open viewController using coding as below in swift

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {

         let mainStoryboardIpad : UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
         let initialViewControlleripad : UIViewController = mainStoryboardIpad.instantiateViewControllerWithIdentifier("Circles") as UIViewController
         self.window = UIWindow(frame: UIScreen.main.bounds)
         self.window?.rootViewController = initialViewControlleripad
         self.window?.makeKeyAndVisible()

         return true
    }

For iOS 13+ (based on an article by dev2qa)
Open SceneDelegate.swift and add following

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

    // If this scene's self.window is nil then set a new UIWindow object to it.
    self.window = self.window ?? UIWindow()

    // Set this scene's window's background color.
    self.window!.backgroundColor = UIColor.red

    // Create a ViewController object and set it as the scene's window's root view controller.
    self.window!.rootViewController = ViewController()

    // Make this scene's window be visible.
    self.window!.makeKeyAndVisible()

    guard scene is UIWindowScene else { return }
}

There is an open-source navigation utility which attempts to make this easier. Example


Swift 3:

This is my preferred approach when presenting a new viewController from the current viewController through the AppDelegate. This way you don't have to completely tear down your view hierarchy when handling a push notification or universal link

if let controller = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "someController") as? SomeController {
    if let window = self.window, let rootViewController = window.rootViewController {
        var currentController = rootViewController
        while let presentedController = currentController.presentedViewController {
            currentController = presentedController
        }
        currentController.present(controller, animated: true, completion: nil)
    }
}

Swift 3

To present the view together with the navigation controller:

let storyboard = UIStoryboard(name: "Main", bundle: nil)
let viewController = storyboard.instantiateViewController(withIdentifier :"InboxViewController") as! InboxViewController
let navController = UINavigationController.init(rootViewController: viewController)

   if let window = self.window, let rootViewController = window.rootViewController {
       var currentController = rootViewController
       while let presentedController = currentController.presentedViewController {
           currentController = presentedController
        }
           currentController.present(navController, animated: true, completion: nil)
   }