Notification Service Extension not getting invoked on macOS

I’m testing remote push notifications on macOS, and although notifications are received and displayed correctly, my Notification Service Extension (NSE) never gets invoked. The extension is properly added as a target in the same app, uses the UNNotificationServiceExtension class, and implements both didReceive(_:withContentHandler:) and serviceExtensionTimeWillExpire(). I’ve also set "mutable-content": 1 in the APNS payload, similar to how it works on iOS — where the same code correctly triggers the NSE. On macOS, however, there’s no sign that the extension process starts or the delegate methods are called.

import UserNotifications

class NotificationService: UNNotificationServiceExtension {
    override func didReceive(_ request: UNNotificationRequest,
                             withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
        let modified = (request.content.mutableCopy() as? UNMutableNotificationContent)
        modified?.title = "[Modified] " + (modified?.title ?? "")
        contentHandler(modified ?? request.content)
    }

    override func serviceExtensionTimeWillExpire() {
        // Called if the extension times out before finishing
    }
}

And the payload used for testing:

{
  "aps": {
    "alert": {
      "title": "Meeting Reminder",
      "body": "Join the weekly sync call"
    },
    "mutable-content": 1
  },
  "MEETING_ORGANIZER": "Alex Johnson"
}

Despite all correct setup steps, the NSE never triggers on macOS (while working fine on iOS). Can anyone confirm whether UNNotificationServiceExtension is fully supported for remote notifications on macOS, or if additional configuration or entitlement is needed?

Have you established that the extension is not being triggered (and how)? Or are you assuming it is not being triggered because the notification content is being shown as sent, and not being modified?

If it is the latter, there are various reasons that the modification is failing:

  1. the extension not being triggered, like you suspect. The reason for this could vary also, from misconfiguration, to incorrect payload. You can check the console log (filter for your app's Bundle ID) and you should be able to see an error or a reason logged, if not being triggered or launched is the case.
  2. extension is crashing at launch. again perhaps due to a configuration issue, or a problem in your code, the extension could be crashing right after launch before it is able to modify the notification (the console log will also show this)
  3. extension being terminated for using too much memory (the limit is 24MB), or taking too long (30 seconds) before it finishes (also console log)
  4. an issue with your code is not calling the completion block, which you would need to debug yourself.

Once you know what the issue is, it will be easier to determine a path for fixing it.


Argun Tekant /  WWDR Engineering / Core Technologies

Thanks for the detailed response.

To clarify and add some details about my testing setup and observations:

Verification that the extension isn’t being triggered:

I’ve confirmed that the Notification Service Extension (NSE) is not being invoked at all and not just failing to modify the content with the following pointers:

  • The didReceive(_:withContentHandler:) and serviceExtensionTimeWillExpire() methods never log or execute (I’ve added multiple test print/log statements and file-based logs for confirmation).

  • The extension process itself does not appear in Console.app or in the process list.

  • On iOS, using the exact same payload and code, I can see clear logs from the extension when it runs — so the extension logic and payload are validated there.

Console logs checked:

  • I’ve filtered the macOS Console for both the main app bundle ID and the extension’s bundle ID. There are no messages indicating the NSE being launched, terminated, or crashing.
  • The system only logs the standard “Received remote notification” message for the main app’s bundle ID.

Extension setup:

  • The NSE target is correctly added to the same macOS app project. It uses the standard UNNotificationServiceExtension class.

  • The extension has a valid Info.plist with the correct NSExtension dictionary (NSExtensionPointIdentifier = com.apple.usernotifications.service).

  • Code signing and entitlements match across the app and extension.

  • The app requests and receives remote notification permissions normally.

Payload details:

The remote notification payload contains "mutable-content": 1 inside the aps dictionary:

{
  "aps": {
    "alert": {
      "title": "Meeting Reminder",
      "body": "Join the weekly sync call"
    },
    "mutable-content": 1
  },
  "MEETING_ORGANIZER": "Alex Johnson"
}

Behavior summary:

On iOS → NSE launches and modifies the notification title (confirmed via logs and on-device display).

On macOS → Notification displays as sent, but no logs, no extension process, and no indication that the NSE was invoked, while remote notifications behavior is working as expected.

If there is any supported way to intercept or modify remote notification content before display on macOS (e.g., using a different extension type, entitlement, or API path), that would also be very helpful to know? Or any other way to check if the NSE/NCE is getting invoked.

Do tell me if you need any details or the full project.

Notification Service Extension not getting invoked on macOS
 
 
Q