Swift - How to open specific view controller when push notification received?

25,945

Solution 1

When you app is in closed state you should check for launch option in

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { }

and call your API.

Example:

if let option = launchOptions {
  let info = option[UIApplicationLaunchOptionsKey.remoteNotification]
  if (info != nil) {
    goAnotherVC()
  }
}

Solution 2

Swift 5

Simply, implement the following function which will be called when the user clicked on the notification.

In AppDelegate:

// This method is called when user clicked on the notification
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void)
{
    // Do whatever you want when the user tapped on a notification
    // If you are waiting for specific data from the notification 
    // (e.g., key: "target" and associated with "value"), 
    // you can capture it as follows then do the navigation:

    // You may print `userInfo` dictionary, to see all data received with the notification.
    let userInfo = response.notification.request.content.userInfo
    if let targetValue = userInfo["target"] as? String, targetValue == "value"
    {
        coordinateToSomeVC()
    }
    
    completionHandler()
}

private func coordinateToSomeVC()
{
    guard let window = UIApplication.shared.keyWindow else { return }

    let storyboard = UIStoryboard(name: "YourStoryboard", bundle: nil) 
    let yourVC = storyboard.instantiateViewController(identifier: "yourVCIdentifier")
    
    let navController = UINavigationController(rootViewController: yourVC)
    navController.modalPresentationStyle = .fullScreen

    // you can assign your vc directly or push it in navigation stack as follows:
    window.rootViewController = navController
    window.makeKeyAndVisible()
}

Note:

If you navigate to a specific controller based on the notification, you should care about how you will navigate back from this controller because there are no controllers in your stack right now. You must instantiate the controller you will back to. In my case, when the user clicked back, I instantiate the home controller and make it the app root again as the app will normally start.

Share:
25,945
PPShein
Author by

PPShein

Updated on February 22, 2021

Comments

  • PPShein
    PPShein over 3 years

    I got stuck specific view controller is not move when I tap on push notification alert when application is not open stage totally.

    Here is my code:

    func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
        /*
    
        fetch and add push notification data
    
         */
        goAnotherVC()
    }
    
    func goAnotherVC() {
        if (application.applicationState == UIApplicationState.active) {
            /* active stage is working */ 
        } else if (application.applicationState == UIApplicationState.inactive || application.applicationState == UIApplicationState.background) {
            if (type == "1" || type == "2") {
                let storyboard: UIStoryboard = UIStoryboard(name: "MyAppointments", bundle: nil)
                let apptVC = storyboard.instantiateViewController(withIdentifier: "NotificationDetailViewController") as! NotificationDetailViewController
                let navigationController = UINavigationController.init(rootViewController: apptVC)
                self.window?.rootViewController = navigationController
                self.window?.makeKeyAndVisible()
            } else if (type == "3") {
                let storyboard: UIStoryboard = UIStoryboard(name: "MyAppointments", bundle: nil)
                let apptVC = storyboard.instantiateViewController(withIdentifier: "NotificationDetailViewController") as! NotificationDetailViewController
                let navigationController = UINavigationController.init(rootViewController: apptVC)
                self.window?.rootViewController = navigationController
                self.window?.makeKeyAndVisible()
            } else if (type == "4") {
                let storyboard: UIStoryboard = UIStoryboard(name: "Enquiry", bundle: nil)
                let enqVC = storyboard.instantiateViewController(withIdentifier: "EnquiryDetailViewController") as! EnquiryDetailViewController
                let navigationController = UINavigationController.init(rootViewController: enqVC)
                self.window?.rootViewController = navigationController
                self.window?.makeKeyAndVisible()
            }
        }
    }
    

    I can get notification and tap to move specific VC when application is active. Please help me what I am missing.

  • Ahmed Safadi
    Ahmed Safadi over 5 years
    where i can found Helper.instance.goToControlllerWith !?
  • Essam Fahmi
    Essam Fahmi over 5 years
    It's a self defined method, using instantiate.
  • Negar Moshtaghi
    Negar Moshtaghi over 3 years
    the main question is about how to show vc which you handle in your helper class
  • Essam Fahmi
    Essam Fahmi over 3 years
    You mean I should clear other functions to focus on the user question?
  • Essam Fahmi
    Essam Fahmi over 3 years
    @NegarMoshtaghi I have edited the answer to be more relative and at the point, check it again.
  • BVB09
    BVB09 about 3 years
    I followed this answer but my app keeps crashing. Any chance you'd be able to take a look at this? stackoverflow.com/questions/67049235/…