Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UNNotificationServiceExtension's didRecieve not called

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)

like image 264
Nitish Avatar asked Aug 07 '18 08:08

Nitish


People also ask

How to send notifications to the device using the notificationserviceextension?

Select Automatically under the Launch option. Run the scheme of the extension (not the parent app). Send your device a notification. Profit. After struggling with this I finally made this work for me by just changing 2 things. The bundleID of the NotificationServiceExtension target must be a different one.

Is the unnotificationserviceextension instance called perfectly great?

After altering the deployment target to 10.0 the UNNotificationServiceExtension instance was called perfectly Great. I did a same mistake. Thanks you so much. Oh my God! This is really nice and simple solution. I didn't even think to check this. Thank you!

When does the system execute my notification content app extension?

The system executes your notification content app extension only when a remote notification’s payload contains the following information: The payload must include the mutable-content key with a value of 1. The payload must include an alert dictionary with title, subtitle, or body information.

What is the bundleid of the notificationserviceextension target?

The bundleID of the NotificationServiceExtension target must be a different one. Preferred style com.companyname.appname.notificationservice (whatever). Setting the same bundleID of the app causes a failure in building to device. The main thing is the deployment target.


Video Answer


1 Answers

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.

like image 183
quellish Avatar answered Nov 03 '22 01:11

quellish