Mukesh R
Mukesh R

Reputation: 33

How to Open a Notification view controller when a iOS push notification is received?

I am working in swift 4.2, and Push notification receive from FireBase. When I tap the Notification, it go to Homepage. But I want to go to Notification page.

This is Swift4.2, Xcode 9.3, iOS 12.1. In the past , I have tried but not working both Foreground and InActive the app

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

        FirebaseApp.configure()

        UINavigationBar.appearance().barTintColor = UIColor(red: 0/255.0, green: 85/255.0, blue: 127/255.0, alpha: 1)
        UINavigationBar.appearance().tintColor = UIColor.white
        //        UINavigationBar.appearance().titleTextAttributes = [NSAttributedString.Key.foregroundColor : UIColor.white,NSAttributedString.Key.font: UIFont(name: "Roboto-Medium", size: 16)!]
        UIBarButtonItem.appearance().setBackButtonTitlePositionAdjustment(UIOffset(horizontal: 0, vertical: -60), for:UIBarMetrics.default)
        UINavigationBar.appearance().isTranslucent = false

        UIApplication.shared.statusBarStyle = .lightContent

        IQKeyboardManager .shared().isEnabled = true
        IQKeyboardManager .shared().shouldResignOnTouchOutside = true
        IQKeyboardManager .shared().isEnableAutoToolbar = false

        if let notification = launchOptions?[.remoteNotification] as? [String: AnyObject] {

            // If your app wasn’t running and the user launches it by tapping the push notification, the push notification is passed to your app in the launchOptions

            let aps = notification["aps"] as! [String: AnyObject]
            UIApplication.shared.applicationIconBadgeNumber = 0


        }            

        if #available(iOS 10.0, *) {
            UNUserNotificationCenter.current().delegate = self
            let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound]
            UNUserNotificationCenter.current().requestAuthorization(
                options: authOptions,
                completionHandler: {_, _ in })
        } else {
            let settings: UIUserNotificationSettings =
                UIUserNotificationSettings(types: [.alert, .badge, .sound], categories: nil)
            application.registerUserNotificationSettings(settings)
        }

        application.registerForRemoteNotifications()


        let mainview = UIStoryboard(name:"Main", bundle: nil).instantiateViewController(withIdentifier: "HomeViewController") as! HomeViewController
        let nav = UINavigationController.init(rootViewController: mainview)
        SideMenu = LGSideMenuController.init(rootViewController: nav)
        SideMenuView = UIStoryboard(name:"Main", bundle: nil).instantiateViewController(withIdentifier: "SideMenuViewController") as! SideMenuViewController
        SideMenu.rightViewStatusBarVisibleOptions = .onAll
        let rect = SideMenuView.view.frame;
        SideMenuView.view.frame = rect


        Messaging.messaging().delegate = self
        //        Siren.shared.wail()

        if launchOptions?[UIApplication.LaunchOptionsKey.remoteNotification] != nil {
            // Do your task here
            let dic = launchOptions?[UIApplication.LaunchOptionsKey.remoteNotification] as? NSDictionary
            let dic2 = dic?.value(forKey: "aps") as? NSDictionary
            let alert = dic2?.value(forKey: "alert") as? NSDictionary
            let category = dic2?.value(forKey: "title") as? String
            // We can add one more key name 'click_action' in payload while sending push notification and check category for indentifying the push notification type. 'category' is one of the seven built in key of payload for identifying type of notification and take actions accordingly
            if category == "News Added"
            {
                /// Set the flag true for is app open from Notification and on root view controller check the flag condition to take action accordingly
                AppConstants.sharedInstance.userDefaults.set(true, forKey: AppConstants.sharedInstance.kisFromNotificationSecond)
            }
            else if category == "1-2-1 notification"
            {
                AppConstants.sharedInstance.userDefaults.set(true, forKey: AppConstants.sharedInstance.kisFromNotificationThird)
            }
        }


        return true
    }

Upvotes: 2

Views: 1674

Answers (2)

Hitesh Surani
Hitesh Surani

Reputation: 13577

For Kill State OR Terminate State:

Define new property in AppDelegate.swift file

var isFromNotification = false

Make below changes in AppDelegate.swift and keep rest of code as it is.

if launchOptions?[UIApplication.LaunchOptionsKey.remoteNotification] != nil {
    isFromNotification = true
    //other required code
}

Goto your Homepage.swift file

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated).
    
    let appDelegate = UIApplication.shared.delegate as! AppDelegate
    if appDelegate.isFromNotification {
        appDelegate.isFromNotification = false
        //Push to your notification controler without animation
    }
}

Update: For Background and Foreground State

Above answer is only work for Kill state as mention in the comment by @Abu Ul Hassan

Now, Let's understand the flow about the background or foreground state.

userNotificationCenter(_:didReceive:withCompletionHandler:) method is called when a user clicks on the notification in background or foreground mode.

func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
    //other required code
    //Get current navigation controller and redirect into notification screen
    completionHandler()
}

How to grab current UIViewController or current UINavigationController

Upvotes: 4

Sparr
Sparr

Reputation: 371

There are two cases to be handled here, one for when the application is alive and the other for when it is not.

When the application is alive, you'll receive a callback in the didReceiveNotificationResponse function of the UserNotificationCenterDelegate. You can process it accordingly.

When the application is being launched, you'll have to use the UIApplication.LaunchOptionsKey.remoteNotification key that you get from didFinishLaunchingWithOptions function in your AppDelegate

Upvotes: 1

Related Questions