Notification Extension — це механізм iOS, який дозволяє модифікувати вміст та зовнішній вигляд push-сповіщень до їх відображення користувачеві. Розширення працюють на стороні операційної системи в окремому процесі: UNNotificationServiceExtension обробляє вхідний контент, а UNNotificationContentExtension керує інтерфейсом. За даними Apple Developer Documentation, 2026, Service Extension отримує до 30 секунд на виконання завдань перед показом сповіщення. Це обмеження критичне під час завантаження вкладень або розшифрування даних.
Головне
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 — це основний інструмент для програмної зміни push-сповіщень до їх показу користувачеві. Розширення активується автоматично при отриманні сповіщення, в пейлоуді якого встановлено прапорець mutable-content: 1. Протягом 30 секунд розширення може завантажити медіа-вкладення, змінити текст, розшифрувати зашифровані дані або збагатити контент.
Розширення реалізує два ключові методи з протоколу UNNotificationServiceExtension. Метод didReceive отримує вхідний запит із сирим UNNotificationRequest та дозволяє модифікувати його через completion handler з новим UNNotificationContent. Метод serviceExtensionTimeWillExpire викликається системою за секунду до закінчення тайм-ауту — в ньому необхідно завершити обробку та передати поточний (можливо, частковий) результат.
Розглянемо сценарій, коли сервер надсилає push з URL зображення в кастомному полі. Service Extension завантажує це зображення по мережі, створює UNNotificationAttachment та додає його в контент. UNNotificationAttachment приймає локальний файл зображення, відео або аудіо та автоматично копіює його в sandbox розширення. Після створення attachment розширення передає оновлений контент системі.
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 дозволяє замінити стандартний банер сповіщення на довільний інтерфейс, створений в Interface Builder або SwiftUI. Розширення активується, коли користувач виконує дію зі сповіщенням: натискання, проведення вниз або 3D Touch. Content Extension отримує контент, вже оброблений Service Extension, та відображає його в кастомному представленні.
Кожен 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 — це об'єкт, який додає медіа-файл до 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 з мінімальними налаштуваннями та вимикати завантаження при слабкому сигналі. Якщо вкладення не завантажилося вчасно, сповіщення показується без медіа — це поведінка системи за замовчуванням.
Розглянемо повний приклад Notification Extension, який завантажує зображення, скачує його та додає до сповіщення. NotificationService успадковується від UNNotificationServiceExtension та перевизначає метод didReceive. У прикладі показано обробку опціональних полів, створення attachment та виклик completion handler з модифікованим контентом.
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. Ключ NSExtensionPointIdentifier встановлюється в com.apple.usernotifications.service для Service Extension або com.apple.usernotifications.content для Content Extension. Категорії визначаються в AppDelegate при запуску застосунку через UNUserNotificationCenter, і розширення активується лише для сповіщень з відповідною категорією в пейлоуді.
Часті запитання
Service Extension модифікує контент до показу сповіщення — додає медіа, змінює текст, розшифровує дані. Content Extension замінює інтерфейс сповіщення на кастомний після взаємодії користувача. Service Extension працює до показу, Content Extension — після.
Система виділяє 30 секунд на виконання коду в didReceive. Якщо обробка не завершена за цей час, викликається serviceExtensionTimeWillExpire, де потрібно передати поточний результат. Рекомендується вкладатися в 10–15 секунд з урахуванням завантаження вкладень.
Так, SwiftUI підтримується в Content Extension починаючи з iOS 16. View обгортається в UIHostingController та додається на storyboard. Однак через ліміти пам'яті рекомендується використовувати SwiftUI лише для простих інтерфейсів з мінімальною кількістю елементів.
При помилці завантаження або перевищенні ліміту часу просто викличте completion handler з вихідним контентом без attachment. Система покаже сповіщення в стандартному вигляді без медіа. Логуйте помилки через OSLog для діагностики, але не блокуйте показ сповіщення.
Розширення працює в ізольованому процесі з лімітом близько 50 MB. При перевищенні система вбиває процес через watchdog. Уникайте завантаження великих файлів, зберігання зображень в пам'яті та витоків при роботі з URLSession.
Підсумки
Ми розробимо мобільний застосунок під ключ
IT Sectr створює застосунки для iOS та Android для стартапів і бізнесу з 2017 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.
Читайте також