UNNotificationServiceExtension's didRecieve not called
Asked Answered
S

1

6

I moved step by step for getting rich push notifications. Here they are :

  1. Created Notification service extension with plist :

enter image description here

NotificationService didRecieve :

override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {

        func failEarly() {
            contentHandler(request.content)
        }

        self.contentHandler = contentHandler
        bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent)

        // Get the custom data from the notification payload
        if let data = request.content.userInfo as? [String: AnyObject] {
            // Grab the attachment
            //            let notificationData = data["data"] as? [String: String]
            if let urlString = data["attachment-url"], let fileUrl = URL(string: urlString as! String) {
                // Download the attachment
                URLSession.shared.downloadTask(with: fileUrl) { (location, response, error) in
                    if let location = location {
                        // Move temporary file to remove .tmp extension
                        let tmpDirectory = NSTemporaryDirectory()
                        let tmpFile = "file://".appending(tmpDirectory).appending(fileUrl.lastPathComponent)
                        let tmpUrl = URL(string: tmpFile)!
                        try! FileManager.default.moveItem(at: location, to: tmpUrl)

                        // Add the attachment to the notification content
                        if let attachment = try? UNNotificationAttachment(identifier: "video", url: tmpUrl, options:nil) {
                            self.bestAttemptContent?.attachments = [attachment]
                        }else if let attachment = try? UNNotificationAttachment(identifier: "image", url: tmpUrl, options:nil) {
                            self.bestAttemptContent?.attachments = [attachment]
                        }else if let attachment = try? UNNotificationAttachment(identifier: "audio", url: tmpUrl, options:nil) {
                            self.bestAttemptContent?.attachments = [attachment]
                        }else if let attachment = try? UNNotificationAttachment(identifier: "image.gif", url: tmpUrl, options: nil) {
                            self.bestAttemptContent?.attachments = [attachment]
                        }
                    }
                    // Serve the notification content
                    self.contentHandler!(self.bestAttemptContent!)
                    }.resume()
            }
        }
    }
  1. Configured AppId and provision profile for extension.

Rich notification is coming correctly :

enter image description here

But here are the issues I am facing :

  1. didRecieve is not getting called. For that I attached the serviceExtension process to the app target and ran the app.
    Note : Extension is getting called as soon as notification arrives but didRecieve is not called :

enter image description here

  1. On opening the push notification (which has video attachment), nothing happens. Ideally it should get played.
  2. If I have to open the video and play it, do I have to explicitly do something or extension will take care of that ?

Payload :

aps =     {
        alert = "This is what your message will look like! Type in your message in the text area and get a preview right here";
        badge = 1;
        "mutable-content" = 1;
        sound = default;
    };
    "attachment-url" = "https://www.sample-videos.com/video/mp4/720/big_buck_bunny_720p_1mb.mp4";
    deeplinkurl = "";
    "message_id" = 1609;
} 

I did try going through following posts but that didn't help :

iOS10 UNNotificationServiceExtension not called
NotificationServiceExtension not called
UNNotificationServiceExtension not working on iPhone 5 (iOS 10)

Sloane answered 7/8, 2018 at 8:22 Comment(0)
G
22

Good news! Your service extension is indeed being called - the image on your notification is evidence of that. What is probably happening here is that you are unable to debug the extension using the workflow you are used to with applications.

Debugging notification extensions is not like debugging an app. Extensions are plug-ins to an iOS process outside your application. Just setting a breakpoint is not a reliable way to debug them. Instead:

Debugging A Notification Service Extension

  1. Launch the app from Xcode or the device
  2. In Xcode, select Attach To Process or PID By Name... from the Debug menu Xcode Debug menu, Attach To Process or PID By Name...
  3. Enter the name of your notification extension Xcode Debug menu, Enter Process Name
  4. Trigger a notification (by sending a push, etc.).

When the notification is delivered the service extension should launch in to the debugger. Service extensions are only relevant to remote (push) notifications, so you will need a device to troubleshoot them.

Debugging A Notification Content Extension There are at least two ways. The steps shown above for a service extension also work for a content extension. The second method is more familiar but less reliable.

  1. Select the extension scheme in Xcode using the toolbar Xcode Scheme Toolbar
  2. In the Product menu, select Edit Scheme... Xcode Edit Scheme..
  3. Set the Executable to the parent application. Xcode Set Executable
  4. Set a breakpoint inside the content extension.
  5. Now build and run your extension. It will launch the parent application.
  6. Trigger a notification that will cause the content extension to load.

It's worth noting that adding logging using the logging framework can be very useful for debugging and troubleshooting as well.

Why The Video May Not Be Playing

iOS limits the size of content that can be presented in notifications. This is described in the documentation for UNNotificationAttachment. For video it is generally 50Mb. Make sure your video is as small as you can make it in terms of bytes, and of course provide a video that is sized appropriately for the device it will be played on. Do not try to play a 1080p video in a notification that is 400 points wide!

In practice it is almost always better to use HLS instead of downloading video, and present it in a content extension.

Another thing in your code that may be problematic is the identifiers you are assigning to your attachments. Identifiers should be unique. Typically this would be a reverse-domain notation string like your bundle ID followed by a UUID string. You could also use the original URL of the content followed by a UUID string. If you provide an empty string iOS will create a unique identifier for you. With the user notifications framework having non-unique identifiers (for notifications, attachments, etc.) tends to cause difficult to track down issues inside the framework. For example, this can cause an attached watchOS device to crash.

If you want to implement "auto play" for your video - it is not clear from your question wether that is what you are describing - you will need to implement your own player functionality in a content extension.

If you are going to do that, again, HLS is the preferred way to display video in a notification. It usually uses less RAM, offers a better user experience and tends to be more stable.

Gilges answered 10/8, 2018 at 4:49 Comment(4)
Thanks for this great explanation. Actually it was my stupidity. Everything was working fine. I was not long pressing the notification which opens the video. Really stupid of me, right :D But I was doing all the steps as you have mentioned.Sloane
What if the extension never gets triggered? I'm sending "mutable-content": 1 and it has an alert, like the apple docs state developer.apple.com/documentation/usernotifications/…, but when i try to attach i only ever see the message "PushService Waiting to attach" I know the notification is getting to the device, as i am toggling the badge count and i see that get updated on the device...Allanallana
@Allanallana I am having the same issue. Also "mutable-content": 1 but my extension is just never called. Did you find a solution to your problem?Primus
Same here, I'm trying using many methods but the extension never gets called. Any working solution?Reisch

© 2022 - 2024 — McMap. All rights reserved.