Notification Service Extension: що це, обробка контенту до показу на iOS

Автор: IT Sectr Опубліковано: 2026-03-21 Час читання: 8 хв

Notification Service Extension — це розширення iOS, яке перехоплює push-сповіщення до його відображення користувачу та дозволяє модифікувати вміст. Розширення може розшифрувати зашифровані дані, завантажити медіавкладення, змінити текст або додати кастомні поля. За даними Apple Developer, 2025, Notification Service Extension має до 30 секунд на виконання завдання у фоновому режимі.

Головне

  • Notification Service Extension — iOS-розширення для обробки push-сповіщення до показу.
  • Розширення успадковується від UNNotificationServiceExtension та реалізує метод didReceive.
  • Доступно до 30 секунд фонового виконання для завантаження та обробки даних.
  • Основні сценарії: розшифровка payload, завантаження зображень і відео, валідація контенту.
  • Розширення може відкласти показ сповіщення або повністю скасувати його через contentHandler.

Що таке Notification Service Extension

Notification Service Extension — це розширення додатку в iOS, яке запускається перед відображенням push-сповіщення. Воно дозволяє серверу надсилати мінімальний payload, а розширенню — доповнювати його контентом: завантажувати зображення, розшифровувати дані, замінювати текст. Користувач бачить вже готове, оброблене сповіщення.

Як це працює

Коли iOS отримує push-сповіщення, система перевіряє наявність розширення для даного додатку. Якщо розширення зареєстровано, iOS запускає його у фоновому процесі та передає вміст сповіщення через метод didReceive(_:withContentHandler:). Розширення обробляє контент та викликає contentHandler з модифікованим вмістом. Якщо розширення не встигає за 30 секунд, система відображає оригінальне сповіщення.

Коли потрібно використовувати Service Extension

Service Extension необхідний у сценаріях, де контент сповіщення потребує обробки на пристрої. Безпечні комунікації: сервер надсилає зашифрований payload, розширення розшифровує його локально. Багаті медіасповіщення: сервер надсилає URL зображення, розширення завантажує та прикріплює його. Динамічна локалізація: розширення підставляє текст мовою пристрою.

СценарійБез розширенняЗ розширенням
ЗображенняНе підтримуєтьсяЗавантажується та відображається
ШифруванняСервер зберігає ключРозшифровка на пристрої
ТекстЖорстко заданий на серверіДинамічна підстановка
ВалідаціяНе перевіряєтьсяСкасування шкідливих сповіщень

Обмеження та час виконання

Notification Service Extension працює в обмеженому середовищі. Максимальний час виконання — 30 секунд. Розширення не має доступу до основного сховища додатку (крім App Group). Розмір розширення обмежений 50 МБ. При перевищенні часу система викликає contentHandler з оригінальним контентом, і всі зміни втрачаються.

Створення розширення та налаштування Info.plist

У Xcode Notification Service Extension додається через створення нового target типу Notification Service Extension. Xcode генерує шаблон класу NotificationService, який успадковує від UNNotificationServiceExtension, з двома методами: didReceive та serviceExtensionTimeWillExpire.

Додавання target у проект

У Xcode виберіть File → New → Target → Notification Service Extension. Вкажіть ім'я (наприклад, PushNotificationService) та мову Swift. Переконайтеся, що target додано до основного додатку та має правильний підпис. Після створення буде згенеровано клас NotificationService.swift з базовою реалізацією.

Структура Info.plist розширення

Info.plist розширення містить ключ NSExtension з підключами NSExtensionPointIdentifier (com.apple.usernotifications.service) та NSExtensionPrincipalClass (ім'я вашого контролера). Додатково можна вказати NSExtensionAttributes з правилами активації розширення. Ці налаштування Xcode генерує автоматично.

Приклад базового розширення

Базова реалізація перевизначає didReceive, модифікує вміст сповіщення та викликає contentHandler. Якщо обробка займає занадто багато часу, викликається serviceExtensionTimeWillExpire, де необхідно завершити роботу з поточним станом.

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 = "[Оброблено] \(bestAttemptContent.title)"
            contentHandler?(bestAttemptContent)
        }
    }

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

Розшифровка зашифрованого payload

Одним із ключових застосувань Service Extension є розшифровка вмісту сповіщення на пристрої. Сервер надсилає зашифрований payload, а розширення розшифровує його, використовуючи ключ, що зберігається в Keychain або App Group. Це гарантує, що контент недоступний для перехоплення під час передачі.

Архітектура безпечної доставки

Сервер шифрує тіло сповіщення з використанням симетричного ключа (AES-256). Ключ шифрування попередньо узгоджується між клієнтом і сервером. Розширення отримує зашифрований рядок у полі data payload, розшифровує його та підставляє в поля сповіщення. Користувацький ключ може бути отриманий з Keychain після аутентифікації.

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)
}

Безпечне зберігання ключів

Ключ для розшифровки не повинен зберігатися в коді розширення або NSUserDefaults. Використовуйте iOS Keychain з доступом через App Group, щоб і додаток, і розширення могли читати ключ. Для генерації ключа на клієнті використовуйте Security.framework з алгоритмом AES-256-GCM.

Завантаження та прикріплення медіавкладень

Найчастіше застосування Notification Service Extension — завантаження зображень, GIF та відео для подальшого відображення в сповіщенні. Сервер надсилає URL медіафайлу, а розширення завантажує його, зберігає в тимчасову директорію та створює UNNotificationAttachment.

Процес завантаження та прикріплення медіа

Розширення отримує URL зображення з поля payload сповіщення. Використовуючи URLSession, розширення завантажує файл у тимчасову директорію. Після завершення завантаження створюється UNNotificationAttachment з локальним URL. Вкладення передається в модифікований контент. iOS автоматично відображає зображення в стандартному інтерфейсі або в 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()
}

Підтримувані формати медіа

iOS підтримує наступні формати для відображення в сповіщеннях: JPEG, PNG, GIF (статичні), MPEG-4 відео до 50 МБ. Для аудіофайлів підтримується MP3, AAC та ALAC. Важливо: всі медіафайли повинні бути завантажені протягом 30-секундного ліміту. Для великих файлів рекомендується використовувати серверне обрізання або прогресивне завантаження.

Управління часом та fallback-сценарії

Управління 30-секундним лімітом — ключове завдання при розробці Notification Service Extension. Якщо розширення не встигає завершити обробку, система викликає serviceExtensionTimeWillExpire та відображає оригінальний контент. Необхідно передбачити fallback-сценарії для кожного типу обробки.

Стратегія пріоритетів

Розділіть завдання за пріоритетами. Критичні модифікації (розшифровка, базова локалізація) виконуйте в першу чергу. Опціональні покращення (завантаження зображень, збагачення тексту) — в другу чергу. Використовуйте URLSession з таймаутами для мережевих запитів, щоб не витрачати весь ліміт на одну операцію.

Fallback при помилках

Якщо завантаження зображення не вдалося або розшифровка payload повернула помилку, розширення повинно викликати contentHandler з оригінальним контентом. Ніколи не завершуйте розширення без виклику contentHandler — це призводить до втрати сповіщення. Безпечний fallback завжди повинен бути передбачений в коді розширення.

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

    // Критичне завдання: розшифровка
    var decryptedContent = tryDecryptPayload(content)

    // Опціональне завдання: медіа
    guard let mediaUrl = decryptedContent.userInfo["media_url"]
        as? String else {
        handler(decryptedContent)
        return
    }

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

Тестування розширення

Для тестування Notification Service Extension використовуйте Xcode: виберіть target розширення, запустіть на симуляторі та надішліть push-сповіщення через термінал або Firebase Console. Логуйте кожен етап обробки через os_log — це допомагає діагностувати проблеми з таймінгами та помилками завантаження.

Часті запитання

Що станеться, якщо розширення не вкладеться в 30 секунд?

Система викличе serviceExtensionTimeWillExpire, після чого відобразить оригінальне сповіщення без змін. Всі завантажені файли та модифікації будуть відкинуті.

Чи можна скасувати показ сповіщення з розширення?

Так, якщо викликати contentHandler з порожнім контентом (UNNotificationContent з порожніми полями), сповіщення не буде показано. Це використовується для фільтрації спам-сповіщень або некоректних даних.

Як передати токен авторизації для завантаження медіа?

Токен можна передати в userInfo payload сповіщення або отримати з Keychain через App Group. Не рекомендується зберігати токени в UserDefaults розширення.

Чи потрібна спеціальна настройка сертифікатів для розширення?

Розширення повинно бути підписано тим же сертифікатом розробника, що й основний додаток. Для продакшену потрібен production-сертифікат з включеним capability Push Notifications.

Як налагодити розширення на реальному пристрої?

Підключіть пристрій до Xcode, виберіть target розширення в схемі запуску та надішліть push-сповіщення через Firebase Console. Breakpoints в розширенні працюють так само, як в основному додатку.

Підсумки

  • Notification Service Extension — iOS-розширення для фонової обробки push-сповіщень до показу.
  • Максимальний час виконання — 30 секунд, після чого система відображає оригінальний контент.
  • Основні застосування: розшифровка payload, завантаження медіа, валідація та локалізація контенту.
  • Розширення успадковується від UNNotificationServiceExtension з методами didReceive та serviceExtensionTimeWillExpire.
  • Для завантаження медіа використовуйте URLSession, для зберігання ключів — iOS Keychain.
  • Завжди передбачайте fallback — викликайте contentHandler з оригінальним контентом при помилках.
  • Комбінуйте Service Extension з Content Extension для повного контролю над сповіщеннями.

Ми розробимо мобільний застосунок під ключ

IT Sectr створює застосунки для iOS та Android для стартапів і бізнесу з 2017 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.

Обговорити проект

Читайте також