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

3

6

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.

Kinshasa answered 15/6, 2018 at 4:51 Comment(5)
Do you want to access notification data before notification arrived ?Dickson
You can access it with NotificationServiceExtension, which are allowed you to access notification response and modify it, then that modified data you can display in notification. But you don't want to modify, then you can display same it is.Dickson
Well thanks, i'm working on your suggestion I'll ping if failsKinshasa
Pleasure mine. I hope you will do it.Dickson
@available(iOS 10.0, *) func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) { let state: UIApplicationState = UIApplication.shared.applicationState if state == .active { // foreground alertRemoteNotification(request.content.userInfo as NSDictionary) } } not working all the time and notification not coming instatly. Got solution without NotificationServiceExtensionKinshasa
T
5

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

Tigress answered 15/6, 2018 at 6:4 Comment(0)
W
2

Create notification service extension to process notification data. you will get 30seconds to process pushnotification via notification service extension

Refer this screenshot

override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
    if let copy = request.content.mutableCopy() as? UNMutableNotificationContent {
        // Process your notification here

        contentHandler(copy)
    }
}

Hope this will help you

Whoremaster answered 15/6, 2018 at 5:48 Comment(0)
K
0
@available(iOS 10.0, *)
    func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {

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

        UIApplication.shared.applicationIconBadgeNumber = 0

        // Added This line
        alertRemoteNotification(notification.request.content.userInfo as NSDictionary) 
    }

Working without any issues.

Kinshasa answered 15/6, 2018 at 6:5 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.