Notification Extension: ключові поняття, типи розширень та налаштування

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

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

Головне

  • Service Extension — перехоплює сповіщення до показу, дозволяє змінювати текст, додавати медіа та розшифровувати дані з обмеженням у 30 секунд.
  • Content Extension — створює кастомний інтерфейс сповіщення з довільним UI, кнопками та обробкою натискань через storyboard або SwiftUI.
  • Медіа-вкладення — зображення, відео та аудіо додаються через UNNotificationAttachment у Service Extension перед передачею Content Extension.
  • Реєстрація — обидва розширення реєструються в Info.plist як окремі target'и із зазначенням категорій сповіщень та NSExtensionPointIdentifier.
  • Обмеження — розширення не мають доступу до основного застосунку, працюють в ізольованій пісочниці з лімітом пам'яті 50 MB.

Що таке Notification Extension

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

Два типи розширень сповіщень

Apple надає два типи Notification Extension для різних цілей: UNNotificationServiceExtension відповідає за обробку вхідного пейлоуда, а UNNotificationContentExtension керує відображенням. Service Extension запускається до показу сповіщення та отримує обмежений час на виконання — до 30 секунд за даними Apple Developer Documentation. Content Extension активується після того, як користувач взаємодіє зі сповіщенням, та відображає кастомний view.

Відмінність від стандартних сповіщень

Стандартне push-сповіщення iOS відображається системою автоматично на основі полів alert, title та subtitle із JSON-пейлоуда. Notification Extension перехоплює керування: Service Extension отримує сирий пейлоуд, модифікує його та передає системі для показу. Content Extension замінює стандартний банер на довільний інтерфейс з будь-якими елементами керування.

Життєвий цикл розширення

Коли пристрій отримує push-сповіщення з ключем mutable-content: 1, система запускає Service Extension в окремому процесі. Процес розширення ізольований від основного застосунку та має власну пісочницю з лімітом пам'яті 50 MB. Після завершення обробки розширення викликає completion handler, передаючи модифікований UNNotificationContent системі для відображення.

UNNotificationServiceExtension: модифікація контенту

UNNotificationServiceExtension — це основний інструмент для програмної зміни push-сповіщень до їх показу користувачеві. Розширення активується автоматично при отриманні сповіщення, в пейлоуді якого встановлено прапорець mutable-content: 1. Протягом 30 секунд розширення може завантажити медіа-вкладення, змінити текст, розшифрувати зашифровані дані або збагатити контент.

Методи протоколу UNNotificationServiceExtension

Розширення реалізує два ключові методи з протоколу UNNotificationServiceExtension. Метод didReceive отримує вхідний запит із сирим UNNotificationRequest та дозволяє модифікувати його через completion handler з новим UNNotificationContent. Метод serviceExtensionTimeWillExpire викликається системою за секунду до закінчення тайм-ауту — в ньому необхідно завершити обробку та передати поточний (можливо, частковий) результат.

Приклад: додавання зображення до сповіщення

Розглянемо сценарій, коли сервер надсилає push з URL зображення в кастомному полі. Service Extension завантажує це зображення по мережі, створює UNNotificationAttachment та додає його в контент. UNNotificationAttachment приймає локальний файл зображення, відео або аудіо та автоматично копіює його в sandbox розширення. Після створення attachment розширення передає оновлений контент системі.

swift
class NotificationService: UNNotificationServiceExtension {

    override func didReceive(_ request: UNNotificationRequest,
        withContentHandler contentHandler:
        @escaping (UNNotificationContent) -> Void) {

        let userInfo = request.content.userInfo
        guard let imageURL = URL(string: userInfo["image-url"] as! String)
        else { contentHandler(request.content); return }

        let attachment = try! UNNotificationAttachment(
            identifier: "image", url: imageURL,
            options: [UNNotificationAttachmentOptionsTypeHintKey: "jpg"])

        let modifiedContent = request.content.mutableCopy()
            as! UNMutableNotificationContent
        modifiedContent.attachments = [attachment]
        contentHandler(modifiedContent)
    }

    override func serviceExtensionTimeWillExpire() {
        contentHandler?(bestAttemptContent ?? request.content)
    }
}

Кешування та повторне використання

При частому надсиланні сповіщень з однаковими вкладеннями рекомендується кешувати завантажені файли на пристрої. FileManager надає доступ до директорії кешу розширення, яка зберігається між запусками. Це зменшує час обробки наступних сповіщень та знижує навантаження на мережу. За даними Apple, кешування вкладень може скоротити час обробки до 2–5 секунд замість повного завантаження.

UNNotificationContentExtension: кастомний інтерфейс

UNNotificationContentExtension дозволяє замінити стандартний банер сповіщення на довільний інтерфейс, створений в Interface Builder або SwiftUI. Розширення активується, коли користувач виконує дію зі сповіщенням: натискання, проведення вниз або 3D Touch. Content Extension отримує контент, вже оброблений Service Extension, та відображає його в кастомному представленні.

Storyboard та категорії сповіщень

Кожен Content Extension прив'язується до однієї або кількох категорій сповіщень через Info.plist. Категорія визначається на сервері полем category в пейлоуді APNS. Система автоматично вибирає потрібний extension на основі категорії отриманого сповіщення. Інтерфейс будується через storyboard з використанням стандартних UIKit-компонентів або SwiftUI View.

Обробка дій користувача

Content Extension підтримує кастомні кнопки та обробники натискань, визначені в UNNotificationAction. UNNotificationAction створюється на етапі реєстрації категорії та може бути текстовим введенням через UNTextInputNotificationAction. Коли користувач натискає кнопку, розширення отримує callback didReceive з ідентифікатором дії та може виконати відповідну логіку — відкрити URL, надіслати запит на сервер або оновити інтерфейс.

Обмеження продуктивності

Content Extension працює в ізольованому процесі з власним циклом виконання та лімітом пам'яті близько 50 MB. Продуктивність розширення критична, оскільки системний watchdog завершує процес при перевищенні лімітів. Рекомендується уникати важких обчислень, завантаження великих зображень та тривалих мережевих запитів всередині Content Extension.

Медіа-вкладення та UNNotificationAttachment

UNNotificationAttachment — це об'єкт, який додає медіа-файл до push-сповіщення: зображення, відео, аудіо або GIF. Вкладення створюється з локального URL файлу, який обов'язково повинен знаходитися в пісочниці розширення. Максимальний розмір вкладення не повинен перевищувати 10 MB, інакше система відхилить attachment при створенні.

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

Apple підтримує обмежений набір форматів для медіа-вкладень. Зображення — JPEG, PNG, GIF (включаючи анімовані), TIFF. Відео — MPEG, MP4, MOV з максимальною тривалістю 30 секунд. Аудіо — MP3, AAC, WAV, CAF. Для кожного формату можна вказати тип через UNNotificationAttachmentOptionsTypeHintKey, що допомагає системі коректно обробити файл.

Завантаження вкладення з мережі

Оскільки push-пейлоуд містить лише URL, а не сам файл, завантаження вкладення потрібно виконувати всередині Service Extension. Максимальний час завантаження обмежений 30 секундами, тому рекомендується використовувати URLSession з мінімальними налаштуваннями та вимикати завантаження при слабкому сигналі. Якщо вкладення не завантажилося вчасно, сповіщення показується без медіа — це поведінка системи за замовчуванням.

Приклад реалізації на Swift

Розглянемо повний приклад Notification Extension, який завантажує зображення, скачує його та додає до сповіщення. NotificationService успадковується від UNNotificationServiceExtension та перевизначає метод didReceive. У прикладі показано обробку опціональних полів, створення attachment та виклик completion handler з модифікованим контентом.

swift
import UserNotifications

class NotificationService: UNNotificationServiceExtension {

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

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

        guard let attachmentURLString =
            bestAttemptContent?.userInfo["attachment-url"] as? String,
            let url = URL(string: attachmentURLString)
        else {
            contentHandler(request.content)
            return
        }

        URLSession.shared.downloadTask(with: url) {
            [weak self] localURL, _, error in
            guard let localURL = localURL, error == nil
            else {
                contentHandler(request.content)
                return
            }
            let attachment = try! UNNotificationAttachment(
                identifier: "media", url: localURL)
            self?.bestAttemptContent?.attachments = [attachment]
            contentHandler(self?.bestAttemptContent
                ?? request.content)
        }.resume()
    }

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

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

Для коректної роботи розширення необхідно зареєструвати категорії сповіщень в Info.plist. Ключ NSExtensionPointIdentifier встановлюється в com.apple.usernotifications.service для Service Extension або com.apple.usernotifications.content для Content Extension. Категорії визначаються в AppDelegate при запуску застосунку через UNUserNotificationCenter, і розширення активується лише для сповіщень з відповідною категорією в пейлоуді.

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

Чим відрізняється Service Extension від Content Extension?

Service Extension модифікує контент до показу сповіщення — додає медіа, змінює текст, розшифровує дані. Content Extension замінює інтерфейс сповіщення на кастомний після взаємодії користувача. Service Extension працює до показу, Content Extension — після.

Скільки часу дається на обробку в Service Extension?

Система виділяє 30 секунд на виконання коду в didReceive. Якщо обробка не завершена за цей час, викликається serviceExtensionTimeWillExpire, де потрібно передати поточний результат. Рекомендується вкладатися в 10–15 секунд з урахуванням завантаження вкладень.

Чи можна використовувати SwiftUI в Content Extension?

Так, SwiftUI підтримується в Content Extension починаючи з iOS 16. View обгортається в UIHostingController та додається на storyboard. Однак через ліміти пам'яті рекомендується використовувати SwiftUI лише для простих інтерфейсів з мінімальною кількістю елементів.

Як обробляти помилки завантаження вкладень?

При помилці завантаження або перевищенні ліміту часу просто викличте completion handler з вихідним контентом без attachment. Система покаже сповіщення в стандартному вигляді без медіа. Логуйте помилки через OSLog для діагностики, але не блокуйте показ сповіщення.

Які обмеження пам'яті у Notification Extension?

Розширення працює в ізольованому процесі з лімітом близько 50 MB. При перевищенні система вбиває процес через watchdog. Уникайте завантаження великих файлів, зберігання зображень в пам'яті та витоків при роботі з URLSession.

Підсумки

  • Notification Extension — механізм iOS для модифікації push-сповіщень, що включає Service Extension (контент) та Content Extension (інтерфейс).
  • Service Extension обробляє пейлоуд до показу сповіщення з лімітом 30 секунд, може додавати медіа-вкладення та розшифровувати дані.
  • Content Extension замінює стандартний банер на кастомний інтерфейс через UIKit або SwiftUI з підтримкою інтерактивних кнопок.
  • UNNotificationAttachment додає зображення, відео та аудіо до сповіщення, підтримуючи формати JPEG, PNG, MP4, MP3 та інші.
  • Реєстрація розширень виконується через Info.plist із зазначенням NSExtensionPointIdentifier та категорій сповіщень для активації.
  • Обмеження — ліміт пам'яті 50 MB, ізольована пісочниця без доступу до основного застосунку, обмежений час виконання.
  • Notification Extension — ключовий інструмент для створення багатих користувацьких сповіщень, що підвищує залученість та функціональність push-комунікацій в iOS.

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

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

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

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