Push Notification in backgroud IOS 10, Swift 3.0, XCode 8

0

I commented that I have migrated my swift app 2.3 to 3.0 and I am working with Xcode 8. with the previous versions I could capture the payload of a push notification using the function: didReceiveRemoteNotification.

I have been trying for several days to capture the payload of the push notification when the app is in background or even closed. I have implemented this:

@available(iOS 10.0, *)
    func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void)
    {
        print("\(notification.request.content.userInfo)")

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

    @available(iOS 10.0, *)
    func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void)
    {
        print("User Info = ",response.notification.request.content.userInfo)

        completionHandler()
    }

but it seems that the second function only responds when the app is opened from the push.

How can I capture the payload information when the app is in background or closed?

    
asked by Christian Gonzalez 06.10.2016 в 00:23
source

2 answers

2

When the app is in background you can capture the payload in this way. If the app is closed there is no way to do it since the code is not running.

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

                   print(userInfo)

             }

Thank you!

    
answered by 12.10.2016 в 13:58
0

In iOS 10 that function is fulfilled by the application extensions. In your case you must use a Notification Service Extension. You can find a good summary here (in English)

In general terms, the Notification Service Extension is a separate binary to your application, which is executed when you receive the push notification before it is displayed. In didReceive you get a UNNotificationRequest , from where you can get all the information (in your case, the payload). That's right, it has a limited execution time, and you can not use methods or classes of UIKit .

I'll give you an example below.

import UserNotifications

class NotificationService: UNNotificationServiceExtension {

    var contentHandler: ((UNNotificationContent) -> Void)?
    var content: UNMutableNotificationContent?

    override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
        self.contentHandler = contentHandler
        self.content = request.content.mutableCopy() as? UNMutableNotificationContent


        if let theContent = self.content
        {
            /* Acá puedes procesar la información a partir del notification content 
            *
            * En este ejemplo consulto el tipo de categoría de la notificación push
            *
            */           
            if theContent.categoryIdentifier == "miCategoria"
            {
                // procesas la información y luego llamas al callback contentHandler. 
                // Tambien puedes modificar el contenido de la notifiación push antes de mostrarla

                contentHandler(theContent)
            }
            else
            {
                contentHandler(request.content)
            }
        }
        else
        {
            contentHandler(request.content)
        }
    }

    override func serviceExtensionTimeWillExpire() {
        // Called just before the extension will be terminated by the system.
        // Use this as an opportunity to deliver your "best attempt" at modified content, otherwise the original push payload will be used.

        print("serviceExtensionTimeWillExpire")

        if let contentHandler = self.contentHandler , let content = self.content
        {
            contentHandler(content)
        }
    }

}
    
answered by 13.10.2016 в 03:36