Back to skills
extension
Category: Development & EngineeringNo API key required

"notification-service"

Notification service extension: rich push notification modification, media attachment downloads, content transformation before display. Use when customizing push notification content, downloading images for notifications, or modifying notification payloads. Triggers: UNNotificationServiceExtension, rich notification, push attachment, notification content.

personAuthor: jakexiaohubgithub

Notification Service

NOTIFICATION SERVICE EXTENSION: SETUP: Requires separate extension target (kind: "notification_service" in plan extensions array). Used to modify rich push notification content before display (add images, decrypt payload, etc.).

PRINCIPAL CLASS (in 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)

    guard let bestAttemptContent else { contentHandler(request.content); return }

    // Modify content here — e.g., download and attach image
    if let urlString = request.content.userInfo["image_url"] as? String,
       let url = URL(string: urlString) {
        downloadAndAttach(url: url, to: bestAttemptContent) { modified in
            contentHandler(modified)
        }
    } else {
        bestAttemptContent.title = "[Modified] " + bestAttemptContent.title
        contentHandler(bestAttemptContent)
    }
}

override func serviceExtensionTimeWillExpire() {
    // Called just before extension is killed — deliver best attempt
    if let contentHandler, let bestAttemptContent {
        contentHandler(bestAttemptContent)
    }
}

}

ADDING ATTACHMENT: func downloadAndAttach(url: URL, to content: UNMutableNotificationContent, completion: @escaping (UNNotificationContent) -> Void) { URLSession.shared.downloadTask(with: url) { localURL, _, _ in if let localURL, let attachment = try? UNNotificationAttachment(identifier: "image", url: localURL) { content.attachments = [attachment] } completion(content) }.resume() }