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 отговаря за обработка на входящия payload, а UNNotificationContentExtension управлява показването. Service Extension се стартира преди показване на известието и има ограничено време за изпълнение — до 30 секунди според Apple Developer Documentation. Content Extension се активира, след като потребителят взаимодейства с известието, и показва персонализиран изглед.

Разлика от стандартните известия

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

Жизнен цикъл на разширението

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

UNNotificationServiceExtension: модификация на съдържание

UNNotificationServiceExtension е основният инструмент за програмна промяна на push известията преди показването им на потребителя. Разширението се активира автоматично при получаване на известие, в чийто payload е зададен флагът mutable-content: 1. В рамките на 30 секунди разширението може да зареди медиен прикачен файл, да промени текст, да декриптира криптирани данни или да обогати съдържанието.

Методи на протокола UNNotificationServiceExtension

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

Пример: добавяне на изображение към известие

Нека разгледаме сценарий, при който сървърът изпраща push с URL на изображение в персонализирано поле. Service Extension зарежда това изображение по мрежата, създава UNNotificationAttachment и го добавя към съдържанието. UNNotificationAttachment приема локален файл с изображение, видео или аудио и автоматично го копира в пясъчната кутия на разширението. След създаване на прикачения файл, разширението предава актуализираното съдържание на системата.

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 payload-а. Системата автоматично избира подходящото разширение на базата на категорията на полученото известие. Интерфейсът се изгражда чрез 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, в противен случай системата ще отхвърли прикачения файл при създаване.

Поддържани формати

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

Зареждане на прикачен файл от мрежата

Тъй като push payload-ът съдържа само URL, а не самия файл, зареждането на прикачения файл трябва да се извърши вътре в Service Extension. Максималното време за зареждане е ограничено до 30 секунди, поради което се препоръчва използването на URLSession с минимални настройки и изключване на зареждането при слаб сигнал. Ако прикаченият файл не се зареди навреме, известието се показва без медия — това е поведението по подразбиране на системата.

Пример за имплементация в Swift

Нека разгледаме пълен пример за Notification Extension, който зарежда изображение, изтегля го и го добавя към известието. NotificationService наследява UNNotificationServiceExtension и преопределя метода didReceive. В примера е показана обработка на опционални полета, създаване на прикачен файл и извикване на 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, и разширението се активира само за известия със съответната категория в payload-а.

Често задавани въпроси

Каква е разликата между 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 с оригиналното съдържание без прикачен файл. Системата ще покаже известието в стандартен вид без медия. Логирайте грешките чрез OSLog за диагностика, но не блокирайте показването на известието.

Какви са ограниченията на паметта на Notification Extension?

Разширението работи в изолиран процес с лимит около 50 MB. При надвишаване на лимита системата убива процеса чрез watchdog. Избягвайте зареждане на големи файлове, съхранение на изображения в паметта и изтичане на памет при работа с URLSession.

Обобщение

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

Ще разработим мобилно приложение под ключ

IT Sectr създава iOS и Android приложения за стартъпи и бизнеси от 2017 г. Ще ви консултираме и ще предложим най-доброто решение.

Обсъдете проекта

Прочетете също