macOS Notification Service killed/fails (but Catalyst/iOS works)

While mutable push notifications process properly in a cousin Catalyst/iOS app, my macOS app does not execute methods in its Notification Service extension to mutate notification content before presentation (when app is active, in background, or terminated).

Console logs (below) show the Mac extension is found and launched, but then killed for "sluggish startup". It is the vanilla new file stub with zero dependencies. I'm doubtful this matters, but I am running Monterey RC1/Xcode 13 RC on an M1.

What am I configuring improperly?

Objective

Push a remote notification ~once a month to download a file, locally process user data, and then silence or display a modified alert accordingly.

I've Tried

Per macOS Notification Service Extension not being used

  • Ensured sandboxed
  • Enabled "Incoming Connection (Server)" (no difference)
  • Wipe DerivedData
  • Run on naive second Mac

Per Notification Service Extension Not working

  • Rebooting the Mac
  • Ensuring the deployment target of the app and extension are identical

Received Notification

From application(_ app: NSApplication, didReceiveRemoteNotification userInfo: [String : Any])

["customThing": value, "aps": {
    alert = "Push Mutable";
    "mutable-content" = 1;
    sound = default;
}]

Signing/Capabilities

App Debug/Release

  • Sanboxed w/ outgoing connections
  • Hardened runtime
  • iCloud
  • Push (certificates)
  • Automatic signing w/ cert

Notifications Extension

  • Sandboxed
  • Hardened runtime
  • Automatic signing

Extension

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 {
            bestAttemptContent.title = "[modified]"
            bestAttemptContent.body = "Changed"
            contentHandler(bestAttemptContent)
        }
    }

    override func serviceExtensionTimeWillExpire() {
        if let contentHandler = contentHandler, let bestAttemptContent =  bestAttemptContent {
            contentHandler(bestAttemptContent)
        }
    }
}

Console

Perhaps relevant?

usernoted <IDENTIFIER> Extension will be killed due to sluggish startup error   serviceExt  com.apple.unc   usernoted

Post not yet marked as solved Up vote post of wingover Down vote post of wingover
3.1k views
  • Universal Scene Description

Add a Comment

Replies

Hi, have you found the solution? I am running into the exact problem, but don't know how to fix it.

+1 on this

+10086