Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to access push notification response without tapping on banner or before showing notification?

I'm implemented push notification in my app in this way

//MARK:- Register notifications

func registerForPushNotifications() {

    if #available(iOS 10.0, *){

        let center = UNUserNotificationCenter.current()
        center.delegate = self
        center.requestAuthorization(options:[.badge, .alert, .sound]) { (granted, error) in
            if (granted)
            {
                UIApplication.shared.registerForRemoteNotifications()
            }
            else{
                //Do stuff if unsuccessful...
            }
            // Enable or disable features based on authorization.
        }
    }

    else
    {
        //If user is not on iOS 10 use the old methods we've been using
        let types: UIUserNotificationType = [UIUserNotificationType.badge, UIUserNotificationType.alert, UIUserNotificationType.sound]
        let settings: UIUserNotificationSettings = UIUserNotificationSettings( types: types, categories: nil )
        UIApplication.shared.registerUserNotificationSettings( settings )
        UIApplication.shared.registerForRemoteNotifications()

    }

}

//MARK: Push Notifications Delegate Methods

func application( _ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data ) {

    var token = ""

    for i in 0..<deviceToken.count {
        //token += String(format: "%02.2hhx", arguments: [chars[i]])
        token = token + String(format: "%02.2hhx", arguments: [deviceToken[i]])
    }

    USER_DEFAULTS.setValue(token, forKey: "Device_ID")

    USER_DEFAULTS.synchronize()

}

func application( _ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error ) {
    print( error.localizedDescription )

}

func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any]) {

    UIApplication.shared.applicationIconBadgeNumber = 0

    alertRemoteNotification(userInfo as NSDictionary)
}

//Code for showing alert when in foreground

func alertRemoteNotification(_ userInfo : NSDictionary)
{
    if UIApplication.shared.applicationState == .active {

        if let aps = userInfo as? NSDictionary {

            if let apsDidt = aps.value(forKey: "aps") as? NSDictionary {

                if let alertDict = apsDidt.value(forKey: "alert") as? NSDictionary {

                    if let notification_type = alertDict.value(forKey: "name") as? String {

                        if let notification_Message = alertDict.value(forKey: "body") as? String {

                            let alert = UIAlertController(title: notification_type.capitalized + " Alert", message: notification_Message, preferredStyle: UIAlertControllerStyle.alert)
                            let okayBtn = UIAlertAction(title: "OK", style: .default, handler: { (action) -> Void in

                                // When Okay

                            UIApplication.shared.applicationIconBadgeNumber = 0

                                if #available(iOS 10.0, *) {

                                    let center = UNUserNotificationCenter.current()
                                    center.removeAllDeliveredNotifications() // To remove all delivered notifications
                                    center.removeAllPendingNotificationRequests()
                                } else {
                                    // Fallback on earlier versions
                                    UIApplication.shared.cancelAllLocalNotifications()
                                }

                                let rootViewController = self.window!.rootViewController as! UINavigationController
                                let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
                                let dashBoardVC = mainStoryboard.instantiateViewController(withIdentifier: "DashBoardVC") as! DashBoardVC
                                rootViewController.pushViewController(dashBoardVC, animated: false)                                    
                            })
                            let cancelBtn = UIAlertAction(title: "Cancel", style: .default, handler: { (action) -> Void in

                                UIApplication.shared.applicationIconBadgeNumber = 0

                                if #available(iOS 10.0, *) {

                                    let center = UNUserNotificationCenter.current()
                                    center.removeAllDeliveredNotifications() // To remove all delivered notifications
                                    center.removeAllPendingNotificationRequests()
                                } else {
                                    // Fallback on earlier versions
                                    UIApplication.shared.cancelAllLocalNotifications()
                                }
                            })
                            alert.addAction(okayBtn)
                            alert.addAction(cancelBtn)

                            self.window?.rootViewController!.present(alert, animated: true, completion: nil)
                        }
                    }
                }
            }
        }
    }
    else {

        let rootViewController = self.window!.rootViewController as! UINavigationController
        let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
        let dashBoardVC = mainStoryboard.instantiateViewController(withIdentifier: "DashBoardVC") as! DashBoardVC
        rootViewController.pushViewController(dashBoardVC, animated: false)
    }
}

//Delegate methods

@available(iOS 10.0, *)
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {

    completionHandler([.sound, .alert, .badge])

    UIApplication.shared.applicationIconBadgeNumber = 0

}

@available(iOS 10.0, *)
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {

    let userInfo = response.notification.request.content.userInfo as NSDictionary

    completionHandler()

    self.alertRemoteNotification(userInfo as NSDictionary)
}

I could able to access the responce after tapping notification banner but the actual issue is when i'm in foreground i need to show an alert with the notification responce without tapping on notification banner. Please let me know how can get responce without tapping on notification banner.

like image 316
Praveen Gowlikar Avatar asked Jun 15 '18 04:06

Praveen Gowlikar


1 Answers

iOS 10+ Provides delegate userNotificationCenter:willPresentNotification:withCompletionHandler

Asks the delegate how to handle a notification that arrived while the app was running in the foreground.

And this will call only if app opened.

Also you can use CONTENT-AVAILABLE=1 for triggering methods.

FLOW:(Without Taping Notification, content-available:1)

App Opened State:- willPresentNotification(ios10+) -> didReceiveRemoteNotification:fetchCompletionHandler

App in Background:- didReceiveRemoteNotification:fetchCompletionHandler

App Closed:- You won't get notification data unless, the app opened by clicking Notification

Alternate method: Using Rich Notification

You can use Notification Extensions to create custom push notifications(contents including images/videos). Notification Service Extension & Notification Content Extension used to achieve this. mutable-content:1 required to trigger this. Here you can download images, get data, etc. [But the data can be shared with App ONLY through UserDefaults(App Groups), correct me if i'm wrong]

You could search for some random tutorials

like image 155
Lal Krishna Avatar answered Sep 30 '22 14:09

Lal Krishna