Notification Service Extension: What It Is, Processing Content Before Display on iOS

Author: IT Sectr Published: 2026-03-21 Reading time: 8 min

Notification Service Extension is an iOS extension that intercepts a push notification before it is displayed to the user and allows modifying the content. The extension can decrypt encrypted data, download media attachments, change text, or add custom fields. According to Apple Developer, 2025, Notification Service Extension has up to 30 seconds to complete the task in the background.

Key Takeaways

  • Notification Service Extension is an iOS extension for processing push notifications before display.
  • The extension inherits from UNNotificationServiceExtension and implements the didReceive method.
  • Up to 30 seconds of background execution for downloading and processing data.
  • Main use cases: decrypting payload, downloading images and videos, content validation.
  • The extension can delay notification display or completely cancel it through contentHandler.

What is Notification Service Extension

Notification Service Extension is an app extension in iOS that runs before a push notification is displayed. It allows the server to send a minimal payload while the extension enriches it with content: downloading images, decrypting data, replacing text. The user sees the already processed notification.

How It Works

When iOS receives a push notification, the system checks if an extension exists for the app. If the extension is registered, iOS launches it in a background process and passes the notification content via the didReceive(_:withContentHandler:) method. The extension processes the content and calls contentHandler with the modified content. If the extension does not complete within 30 seconds, the system displays the original notification.

When to Use Service Extension

Service Extension is needed in scenarios where notification content requires on-device processing. Secure communications: the server sends an encrypted payload, the extension decrypts it locally. Rich media notifications: the server sends an image URL, the extension downloads and attaches it. Dynamic localization: the extension substitutes text in the device language.

ScenarioWithout ExtensionWith Extension
ImageNot supportedDownloaded and displayed
EncryptionServer stores the keyDecryption on device
TextHardcoded on the serverDynamic substitution
ValidationNot checkedMalicious notifications cancelled

Limitations and Execution Time

Notification Service Extension runs in a limited environment. Maximum execution time is 30 seconds. The extension does not have access to the main app storage (except App Group). The extension size is limited to 50 MB. When time exceeds, the system calls contentHandler with the original content, and all changes are lost.

Creating the Extension and Configuring Info.plist

In Xcode, Notification Service Extension is added by creating a new target of type Notification Service Extension. Xcode generates a template NotificationService class inheriting from UNNotificationServiceExtension, with two methods: didReceive and serviceExtensionTimeWillExpire.

Adding a Target to the Project

In Xcode, select File → New → Target → Notification Service Extension. Enter a name (e.g., PushNotificationService) and choose Swift language. Make sure the target is added to the main app and has the correct signing. After creation, the NotificationService.swift class with a basic implementation will be generated.

Extension Info.plist Structure

The extension Info.plist contains the NSExtension key with subkeys NSExtensionPointIdentifier (com.apple.usernotifications.service) and NSExtensionPrincipalClass (your controller name). Additionally, NSExtensionAttributes can be specified with extension activation rules. Xcode generates these settings automatically.

Basic Extension Example

The basic implementation overrides didReceive, modifies the notification content, and calls contentHandler. If processing takes too long, serviceExtensionTimeWillExpire is called, where you need to complete work with the current state.

swift
import UserNotifications

class NotificationService: UNNotificationServiceExtension {

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

    override func didReceive(
        request: UNNotificationRequest,
        withContentHandler handler: @escaping (UNNotificationContent) -> Void
    ) {
        contentHandler = handler
        bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent)

        if let bestAttemptContent = bestAttemptContent {
            bestAttemptContent.title = "[Processed] \(bestAttemptContent.title)"
            contentHandler?(bestAttemptContent)
        }
    }

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

Decrypting the Encrypted Payload

One of the key uses of Service Extension is decrypting notification content on the device. The server sends an encrypted payload, and the extension decrypts it using a key stored in Keychain or App Group. This ensures the content is not interceptable during transmission.

Secure Delivery Architecture

The server encrypts the notification body using a symmetric key (AES-256). The encryption key is pre-agreed between the client and server. The extension receives the encrypted string in the data field of the payload, decrypts it, and substitutes it into the notification fields. The user key can be obtained from Keychain after authentication.

swift
override func didReceive(
    request: UNNotificationRequest,
    withContentHandler handler: @escaping (UNNotificationContent) -> Void
) {
    guard let content = request.content.mutableCopy()
        as? UNMutableNotificationContent else {
        handler(request.content)
        return
    }

    guard let encryptedData = content.userInfo["encrypted_data"]
        as? String else {
        handler(content)
        return
    }

    let decrypted = CryptoService.decrypt(encryptedData)
    content.body = decrypted.body
    content.title = decrypted.title
    handler(content)
}

Secure Key Storage

The decryption key must not be stored in the extension code or NSUserDefaults. Use iOS Keychain with access via App Group so that both the app and the extension can read the key. Use Security.framework with AES-256-GCM algorithm for key generation on the client.

Downloading and Attaching Media Attachments

The most common use of Notification Service Extension is downloading images, GIFs, and videos for display in the notification. The server sends a media file URL, and the extension downloads it, saves it to a temporary directory, and creates a UNNotificationAttachment.

Media Download and Attachment Process

The extension receives the image URL from the notification payload field. Using URLSession, the extension downloads the file to a temporary directory. After download completes, a UNNotificationAttachment with the local URL is created. The attachment is passed to the modified content. iOS automatically displays the image in the standard interface or in a Notification Content Extension.

swift
private func downloadAndAttachMedia(
    content: UNMutableNotificationContent,
    mediaUrl: String,
    handler: @escaping (UNNotificationContent) -> Void
) {
    guard let url = URL(string: mediaUrl) else {
        handler(content)
        return
    }

    let task = URLSession.shared.downloadTask(with: url) { localUrl, _, error in
        guard let localUrl = localUrl, error == nil else {
            handler(content)
            return
        }

        let attachment = try? UNNotificationAttachment(
            identifier: "media",
            url: localUrl,
            options: nil
        )

        if let attachment = attachment {
            content.attachments = [attachment]
        }
        handler(content)
    }
    task.resume()
}

Supported Media Formats

iOS supports the following formats for notification display: JPEG, PNG, GIF (static), MPEG-4 video up to 50 MB. For audio files, MP3, AAC, and ALAC are supported. Important: all media files must be downloaded within the 30-second limit. For large files, server-side cropping or progressive loading is recommended.

Time Management and Fallback Scenarios

Managing the 30-second limit is a key task when developing Notification Service Extension. If the extension does not complete processing in time, the system calls serviceExtensionTimeWillExpire and displays the original content. Fallback scenarios must be provided for each type of processing.

Priority Strategy

Divide tasks by priority. Perform critical modifications (decryption, basic localization) first. Optional improvements (image downloading, text enrichment) come second. Use URLSession with timeouts for network requests to avoid spending the entire limit on a single operation.

Error Fallback

If image download fails or payload decryption returns an error, the extension should call contentHandler with the original content. Never terminate the extension without calling contentHandler — this leads to notification loss. A safe fallback should always be implemented in the extension code.

swift
override func didReceive(
    request: UNNotificationRequest,
    withContentHandler handler: @escaping (UNNotificationContent) -> Void
) {
    let content = (request.content.mutableCopy()
        as? UNMutableNotificationContent) ?? request.content

    // Critical task: decryption
    var decryptedContent = tryDecryptPayload(content)

    // Optional task: media
    guard let mediaUrl = decryptedContent.userInfo["media_url"]
        as? String else {
        handler(decryptedContent)
        return
    }

    downloadAndAttachMedia(
        content: decryptedContent,
        mediaUrl: mediaUrl,
        handler: handler
    )
}

Testing the Extension

To test Notification Service Extension, use Xcode: select the extension target, run on the simulator, and send a push notification via terminal or Firebase Console. Log each processing stage using os_log — this helps diagnose timing and download issues.

Frequently Asked Questions

What happens if the extension does not complete within 30 seconds?

The system calls serviceExtensionTimeWillExpire, then displays the original notification unchanged. All downloaded files and modifications are discarded.

Can notification display be cancelled from the extension?

Yes, if you call contentHandler with empty content (UNNotificationContent with empty fields), the notification will not be displayed. This is used for filtering spam notifications or invalid data.

How to pass an authorization token for media download?

The token can be passed in the userInfo of the notification payload or retrieved from Keychain via App Group. It is not recommended to store tokens in the extension UserDefaults.

Is special certificate configuration required for the extension?

The extension must be signed with the same developer certificate as the main app. For production, a production certificate with the Push Notifications capability enabled is required.

How to debug the extension on a real device?

Connect the device to Xcode, select the extension target in the run scheme, and send a push notification via Firebase Console. Breakpoints in the extension work the same as in the main app.

Summary

  • Notification Service Extension is an iOS extension for background processing of push notifications before display.
  • Maximum execution time is 30 seconds, after which the system displays the original content.
  • Main use cases: payload decryption, media download, content validation and localization.
  • The extension inherits from UNNotificationServiceExtension with didReceive and serviceExtensionTimeWillExpire methods.
  • Use URLSession for media downloads, iOS Keychain for key storage.
  • Always provide a fallback — call contentHandler with original content on errors.
  • Combine Service Extension with Content Extension for full notification control.

We will develop a mobile application turnkey

IT Sectr creates iOS and Android applications for startups and businesses since 2017. We will advise you and propose the best solution.

Discuss the project

Read also