Awais Fayyaz
Awais Fayyaz

Reputation: 2415

Why notification service extension is not firing on iOS 14?

I have integrated UNNotificationServiceExtension which allows me to change the push notification title before it's presented to the user.

I have followed the guidelines mentioned in apple developer documentation and also browsed related questions at SO, But nothing seems to be working.


As directed, i have followed these guidelines


The problem

My notification service extension is not triggered sometimes when push notification is received, mostly when i delete and install a fresh copy of app. Breakpoints also don't get triggered in this case. It looks like system forgets to fire the service extension. I have selected the correct scheme of extension and not the main app target. My notification title is not updated as per my logic.

Note: This is occurring on iOS 14. on iOS 12, it is working fine. Is this an iOS bug?

This is already being discussed in these threads.

https://developer.apple.com/forums/thread/67202 https://developer.apple.com/forums/thread/125987

Any help would be much appreciated. Thanks

Sample Code

I made a sample project to demonstrate this issue. You can download it from Github Repo

Related WWDC Video

Best Practices and What’s New in User Notifications

Upvotes: 5

Views: 8694

Answers (3)

ANASS LAKTAIBI
ANASS LAKTAIBI

Reputation: 61

The only solution that was worked for me (21/07/2023) is :

  1. Uncheck "Copy When Installing".
  2. Remove the notification service extension from "Frameworks" and add it again (re-boot your iPhone).

Upvotes: 5

Awais Fayyaz
Awais Fayyaz

Reputation: 2415

Update

I had submitted Techinical support Incident for this issue. I had performed extensive R & D on the notification service extension. implemented it according to apple docs in a vanila project. Our configuration and everything seemed to be correct. So i requested apple technical support on the issue and got this reply.

We have determined that you are seeing this issue due to a bug in iOS. Please submit a complete bug report regarding this issue using Feedback Assistant (https://feedbackassistant.apple.com). For more information on Feedback Assistant, please visit https://developer.apple.com/bug-reporting/.

Please include all the information you provided me once again in the bug report (you can attach the logs directly to the bug report). Please make sure to follow the instructions at https://developer.apple.com/bug-reporting/profiles-and-logs/ and follow the instructions for APNS (Apple Push Notification Service) to install a logging profile on your device, and make sure it is installed before reproducing the problem.

Important: In Feedback Assistant, when filing bug reports about an API/SDK on macOS, iOS, watchOS or tvOS, please select an appropriate API/SDK area (after "Something else not in this list”).

So, i am going to submit a bug report to apple. i will update this answer once got reply on the bug report.

Upvotes: 1

Virender
Virender

Reputation: 168

You have to modify the UNNotificationRequest content part. Below is the code snippet which I have used for my notification extension.

import UserNotifications

class NotificationService: UNNotificationServiceExtension {

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

    override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
        self.contentHandler = contentHandler
        bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent)
        
        if let bestAttemptContent = bestAttemptContent {
            var urlString:String? = nil
            if let urlImageString = request.content.userInfo["urlImageString"] as? String {
                urlString = urlImageString
            }
            // You can set what ever title you want to set
            bestAttemptContent.title = "Your custom tile goes here"
            if urlString != nil, let fileUrl = URL(string: urlString!) {
                print("fileUrl: \(fileUrl)")
                
                guard let imageData = NSData(contentsOf: fileUrl) else {
                    contentHandler(bestAttemptContent)
                    return
                }
                guard let attachment = UNNotificationAttachment.saveImageToDisk(fileIdentifier: "image.jpg", data: imageData, options: nil) else {
                    print("error in UNNotificationAttachment.saveImageToDisk()")
                    contentHandler(bestAttemptContent)
                    return
                }
                
                bestAttemptContent.attachments = [ attachment ]
            }
            
            contentHandler(bestAttemptContent)
        }
    }
    
    override func serviceExtensionTimeWillExpire() {
        if let contentHandler = contentHandler, let bestAttemptContent =  bestAttemptContent {
            contentHandler(bestAttemptContent)
        }
    }

}

@available(iOSApplicationExtension 10.0, *)
extension UNNotificationAttachment {
    
    static func saveImageToDisk(fileIdentifier: String, data: NSData, options: [NSObject : AnyObject]?) -> UNNotificationAttachment? {
        let fileManager = FileManager.default
        let folderName = ProcessInfo.processInfo.globallyUniqueString
        let folderURL = NSURL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent(folderName, isDirectory: true)
        
        do {
            try fileManager.createDirectory(at: folderURL!, withIntermediateDirectories: true, attributes: nil)
            let fileURL = folderURL?.appendingPathComponent(fileIdentifier)
            try data.write(to: fileURL!, options: [])
            let attachment = try UNNotificationAttachment(identifier: fileIdentifier, url: fileURL!, options: options)
            return attachment
        } catch let error {
            print("error \(error)")
        }
        
        return nil
    }
}

The JSON payload which I have used

{
  "aps": {
    "alert": {
      "title": "title",
      "body": "Your message Here"
    },
    "mutable-content": 1
  },
  "urlImageString": "https://cdn.pixabay.com/photo/2015/04/23/22/00/tree-736885__340.jpg"
}

with your code repo the output which I am getting is as enter image description here

If you want to debug the Notification Service extension then you have to select the Notification Service Extension scheme from the drop down and then your breakpoints will work for you

Upvotes: 2

Related Questions