Notification Content Extension — это тип расширения iOS, который заменяет стандартный шаблон push-уведомления на полностью кастомный пользовательский интерфейс. Разработчик получает возможность отображать изображения, аудиоплеер, кнопки действий, прогресс-бары и кастомную анимацию внутри уведомления, расширяя стандартный баннер до полноценного мини-приложения. По данным WWDC 2025, расширение использует UNNotificationContentExtension и поддерживает до 4 медиавложений в одном уведомлении, а также обработку интерактивных действий через UNNotificationAction.
Главное
Notification Content Extension — это app extension, которое переопределяет отображение push-уведомления на iOS. Вместо стандартного баннера с заголовком, телом сообщения и кнопками можно показать интерфейс, полностью разработанный в Interface Builder или программно через UIKit или SwiftUI.
В отличие от Notification Service Extension, который изменяет содержимое до показа, Content Extension отвечает только за визуальное представление. Расширение получает готовое уведомление после всех модификаций и решает, как его отобразить. Это ключевое различие между двумя типами расширений уведомлений.
Расширение активируется, когда пользователь выполняет жест расширения — прокручивает уведомление вниз или нажимает на него (в зависимости от модели устройства). iOS запускает процесс расширения, создаёт контроллер из указанного nib или storyboard и передаёт уведомление через UNNotificationContentExtension.
Разработка начинается с добавления нового target в Xcode с шаблоном Notification Content Extension. Xcode создаёт файл MainInterface.storyboard и класс, наследующий от UIViewController, реализующий протокол UNNotificationContentExtension.
Максимальная высота кастомной области — 320 точек на iPhone (для моделей с большим экраном) и 352 точки на iPad. Контент, выходящий за эти границы, обрезается. Для адаптации к разным размерам рекомендуется использовать Auto Layout и UIScrollView для прокручиваемого контента. Ширина всегда равна ширине уведомления и меняется автоматически при повороте устройства.
Apple Human Interface Guidelines предупреждают: интерфейс уведомления должен быть лаконичным и содержать только один основной элемент — изображение, плеер, карту или форму быстрого ввода. Множественные интерактивные элементы перегружают пользователя и усложняют взаимодействие.
App Group — единственный механизм обмена данными между расширением и основным приложением. Через общую директорию App Group можно передавать кэшированные изображения, токены и настройки. Прямые вызовы API основного приложения или доступ к его UserDefaults недоступны из-за изоляции процессов.
class NotificationViewController: UIViewController {
func didReceive(
_ notification: UNNotification
) {
guard let attachment = notification
.request.content.attachments.first()
else { return }
if attachment.url.startAccessingSecurityScopedResource() {
imageView.image = UIImage(contentsOfFile:
attachment.url.path)
attachment.url.stopAccessingSecurityScopedResource()
}
}
}
UNNotificationContentExtension — основной протокол, который определяет жизненный цикл кастомного уведомления. Протокол предоставляет методы для получения контента, обработки действий и управления интерфейсом.
didReceive(_:with:) вызывается при получении уведомления. Расширение получает объект UNNotification и UNNotificationContentExtensionMediaPlayPauseButtonType для управления медиаплеером. В этом методе нужно настроить интерфейс — загрузить изображение, инициализировать плеер или отобразить данные. Система вызывает этот метод каждый раз при обновлении уведомления в режиме реального времени.
Важно учитывать, что расширение имеет ограниченное время на выполнение — около 30 секунд на полный цикл отображения. Если интерфейс не будет подготовлен за это время, iOS покажет системное уведомление. Для тяжёлых ресурсов — загрузка изображений из сети, декодирование видео — рекомендуется использовать асинхронные операции с предварительным кэшированием через App Group.
Протокол включает опциональные методы для кнопок play/pause: mediaPlay, mediaPause и mediaPlayPauseButtonType. Если уведомление содержит аудио- или видеоконтент, расширение может показать встроенный плеер с системным элементом управления. iOS автоматически добавляет кнопку воспроизведения в правый верхний угол расширения при возврате соответствующего типа кнопки.
UNNotificationAttachment — объект, который содержит медиаданные, прикреплённые к уведомлению. Изображения, аудиофайлы и видео добавляются на этапе создания уведомления на сервере или в Notification Service Extension через UNNotificationAttachment.
Для изображений: JPEG, PNG, GIF, HEIF. Для аудио: MP3, AAC, ALAC, WAV. Для видео: MPEG-4, H.264, HEVC. Максимальный размер каждого вложения — 50 МБ, до 4 вложений на одно уведомление. Система автоматически скачивает вложения в фоновом режиме до отображения уведомления и предоставляет расширению доступ к локальным URL через security-scoped ресурсы.
По данным Apple, расширение не должно загружать медиа самостоятельно — UNNotificationAttachment уже содержит локальный URL после завершения загрузки системой. Однако если вложение не было загружено вовремя (например, при плохом соединении), расширение может отобразить placeholder или текст альтернативы.
Каждый UNNotificationAttachment предоставляет security-scoped URL, к которому расширение должно получить доступ через startAccessingSecurityScopedResource() и освободить через stopAccessingSecurityScopedResource(). Эти методы должны вызываться парно — иначе ресурс не будет освобождён и вызовет утечку прав доступа.
let attachment = notification.request.content.attachments.first()
guard attachment.url.startAccessingSecurityScopedResource()
else { return }
defer { attachment.url.stopAccessingSecurityScopedResource() }
let data = try Data(contentsOf: attachment.url)
imageView.image = UIImage(data: data)
Notification Content Extension поддерживает кастомные интерактивные действия — кнопки, которые отображаются под содержимым уведомления. Действия регистрируются при создании категории уведомления через UNNotificationCategory и могут быть деструктивными, текстовыми или фоновыми.
UNNotificationAction — простое действие с заголовком и опциональным флагом деструктивности. UNTextInputNotificationAction — действие с полем ввода текста, например для быстрого ответа на сообщение. Оба типа поддерживают опцию UNNotificationActionOptions.authenticationRequired — требование разблокировки устройства перед выполнением.
Расширение получает выбранное действие через метод didReceive(_:withCompletionHandler:), где передаётся объект UNNotificationResponse с идентификатором действия и опциональным текстом. Расширение может обработать ответ самостоятельно или передать его основному приложению через общий контейнер App Group.
let category = UNNotificationCategory(
identifier: "message",
actions: [
UNTextInputNotificationAction(
identifier: "reply",
title: "Reply",
options: .authenticationRequired
),
UNNotificationAction(
identifier: "mark_read",
title: "Mark Read",
options: .foreground
)
],
intentIdentifiers: []
)
Часто задаваемые вопросы
Content Extension отвечает за визуальное отображение уведомления, а Service Extension — за изменение содержимого до показа. Content Extension работает после Service Extension и не может изменить payload уведомления.
Swift и Objective-C для UIKit. С iOS 16 также поддерживается SwiftUI для создания интерфейса уведомления через NotificationContentView с модификаторами размера и конфигурации.
Да, с iOS 16 расширение может использовать SwiftUI через UIHostingController. Однако все компетенции UIKit — размер, ограничения, security-scoped ресурсы — сохраняются и применяются к SwiftUI-контенту.
До 4 вложений на одно уведомление. Каждое вложение размером до 50 МБ. Поддерживаются изображения (JPEG, PNG, HEIF), аудио (MP3, AAC) и видео (MPEG-4, H.264).
Через App Group — общую директорию на диске. UserDefaults с суффиксом app group тоже работает. Прямые вызовы API главного приложения недоступны из-за изоляции процессов расширения.
Итоги
Мы разработаем мобильное приложение под ключ
IT Sectr создаёт приложения для iOS и Android для стартапов и бизнеса с 2017 года. Мы проконсультируем вас и предложим наилучшее решение.
Читайте также