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 года. Мы проконсультируем вас и предложим наилучшее решение.

Обсудить проект

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