Notification Extension je mechanismus iOS, který umožňuje upravit obsah a vzhled push notifikací před jejich zobrazením uživateli. Rozšíření pracují na straně operačního systému v samostatném procesu: UNNotificationServiceExtension zpracovává příchozí obsah a UNNotificationContentExtension spravuje rozhraní. Podle Apple Developer Documentation, 2026 má Service Extension až 30 sekund na provedení úkolů před zobrazením notifikace. Toto omezení je kritické při načítání příloh nebo dešifrování dat.
Hlavní body
Notification Extension je softwarová komponenta iOS, která rozšiřuje standardní chování push notifikací přidáním možnosti úpravy obsahu a přizpůsobení rozhraní. Na rozdíl od běžných notifikací, které systém zobrazuje ve standardní podobě, umožňují rozšíření vývojáři ovlivnit obsah před zobrazením a vytvořit jedinečné uživatelské rozhraní.
Apple poskytuje dva typy Notification Extension pro různé účely: UNNotificationServiceExtension je zodpovědný za zpracování příchozího payloadu a UNNotificationContentExtension spravuje zobrazení. Service Extension se spouští před zobrazením notifikace a má omezený čas na provedení — až 30 sekund podle Apple Developer Documentation. Content Extension se aktivuje poté, co uživatel interaguje s notifikací, a zobrazí vlastní pohled.
Standardní push notifikace iOS je automaticky zobrazena systémem na základě polí alert, title a subtitle z JSON-payloadu. Notification Extension přebírá kontrolu: Service Extension obdrží hrubý payload, upraví jej a předá systému k zobrazení. Content Extension nahrazuje standardní banner libovolným rozhraním s jakýmikoli ovládacími prvky.
Když zařízení obdrží push notifikaci s klíčem mutable-content: 1, systém spustí Service Extension v samostatném procesu. Proces rozšíření je izolován od hlavní aplikace a má vlastní sandbox s limitem paměti 50 MB. Po dokončení zpracování rozšíření zavolá completion handler a předá upravený UNNotificationContent systému k zobrazení.
UNNotificationServiceExtension je hlavní nástroj pro programovou úpravu push notifikací před jejich zobrazením uživateli. Rozšíření se automaticky aktivuje při přijetí notifikace, jejíž payload má nastaven příznak mutable-content: 1. Během 30 sekund může rozšíření načíst přílohu média, změnit text, dešifrovat zašifrovaná data nebo obohatit obsah.
Rozšíření implementuje dvě klíčové metody z protokolu UNNotificationServiceExtension. Metoda didReceive přijímá příchozí požadavek s hrubým UNNotificationRequest a umožňuje jeho úpravu přes completion handler s novým UNNotificationContent. Metoda serviceExtensionTimeWillExpire je volána systémem sekundu před vypršením časového limitu — v ní je třeba dokončit zpracování a předat aktuální (případně částečný) výsledek.
Uvažujme scénář, kdy server odešle push s URL obrázku ve vlastním poli. Service Extension načte tento obrázek přes síť, vytvoří UNNotificationAttachment a přidá jej k obsahu. UNNotificationAttachment přijímá lokální soubor obrázku, videa nebo zvuku a automaticky jej zkopíruje do sandboxu rozšíření. Po vytvoření přílohy rozšíření předá aktualizovaný obsah systému.
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)
}
}
Při častém odesílání notifikací se stejnými přílohami se doporučuje ukládat stažené soubory do mezipaměti na zařízení. FileManager poskytuje přístup k adresáři mezipaměti rozšíření, který je zachován mezi spuštěními. To zkracuje dobu zpracování následujících notifikací a snižuje zatížení sítě. Podle Apple může ukládání příloh do mezipaměti zkrátit dobu zpracování na 2–5 sekund namísto plného načítání.
UNNotificationContentExtension umožňuje nahradit standardní banner notifikace vlastním rozhraním vytvořeným v Interface Builder nebo SwiftUI. Rozšíření se aktivuje, když uživatel provede akci s notifikací: dotyk, přejetí dolů nebo 3D Touch. Content Extension obdrží obsah již zpracovaný Service Extension a zobrazí jej ve vlastním pohledu.
Každý Content Extension je vázán na jednu nebo více kategorií notifikací přes Info.plist. Kategorie je určena na serveru polem category v payloadu APNS. Systém automaticky vybere správné rozšíření na základě kategorie přijaté notifikace. Rozhraní se vytváří přes storyboard pomocí standardních UIKit komponent nebo SwiftUI View.
Content Extension podporuje vlastní tlačítka a obsluhu dotyků definovaných v UNNotificationAction. UNNotificationAction se vytváří ve fázi registrace kategorie a může být zadávání textu přes UNTextInputNotificationAction. Když uživatel stiskne tlačítko, rozšíření obdrží callback didReceive s identifikátorem akce a může provést odpovídající logiku — otevřít URL, odeslat požadavek na server nebo aktualizovat rozhraní.
Content Extension pracuje v izolovaném procesu s vlastní smyčkou provádění a limitem paměti přibližně 50 MB. Výkon rozšíření je kritický, protože systémový watchdog ukončí proces při překročení limitů. Doporučuje se vyhnout se těžkým výpočtům, načítání velkých obrázků a dlouhým síťovým požadavkům uvnitř Content Extension.
UNNotificationAttachment je objekt, který přidává mediální soubor k push notifikaci: obrázek, video, zvuk nebo GIF. Příloha se vytváří z lokálního URL souboru, který musí být v sandboxu rozšíření. Maximální velikost přílohy nesmí přesáhnout 10 MB, jinak systém přílohu při vytváření odmítne.
Apple podporuje omezenou sadu formátů pro mediální přílohy. Obrázky — JPEG, PNG, GIF (včetně animovaných), TIFF. Video — MPEG, MP4, MOV s maximální délkou 30 sekund. Zvuk — MP3, AAC, WAV, CAF. Pro každý formát lze specifikovat typ přes UNNotificationAttachmentOptionsTypeHintKey, což pomáhá systému správně zpracovat soubor.
Vzhledem k tomu, že push payload obsahuje pouze URL, nikoli samotný soubor, načítání přílohy musí proběhnout uvnitř Service Extension. Maximální doba načítání je omezena na 30 sekund, proto se doporučuje používat URLSession s minimálním nastavením a vypnout načítání při slabém signálu. Pokud se příloha nenačte včas, notifikace se zobrazí bez médií — toto je výchozí chování systému.
Podívejme se na úplný příklad Notification Extension, který načte obrázek, stáhne jej a přidá k notifikaci. NotificationService dědí z UNNotificationServiceExtension a přepisuje metodu didReceive. V příkladu je ukázáno zpracování volitelných polí, vytvoření přílohy a volání completion handleru s upraveným obsahem.
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)
}
}
}
Pro správnou funkci rozšíření je třeba zaregistrovat kategorie notifikací v Info.plist. Klíč NSExtensionPointIdentifier se nastavuje na com.apple.usernotifications.service pro Service Extension nebo com.apple.usernotifications.content pro Content Extension. Kategorie se definují v AppDelegate při spuštění aplikace přes UNUserNotificationCenter a rozšíření se aktivuje pouze pro notifikace s odpovídající kategorií v payloadu.
Často kladené otázky
Service Extension upravuje obsah před zobrazením notifikace — přidává média, mění text, dešifruje data. Content Extension nahrazuje rozhraní notifikace vlastním po interakci uživatele. Service Extension pracuje před zobrazením, Content Extension — po něm.
Systém přiděluje 30 sekund na provedení kódu v didReceive. Pokud zpracování není v tomto čase dokončeno, je volána serviceExtensionTimeWillExpire, kde je třeba předat aktuální výsledek. Doporučuje se vejít se do 10–15 sekund s ohledem na načítání příloh.
Ano, SwiftUI je podporováno v Content Extension od iOS 16. View se zabalí do UIHostingController a přidá na storyboard. Kvůli paměťovým limitům se však doporučuje používat SwiftUI pouze pro jednoduchá rozhraní s minimálním počtem prvků.
Při chybě načítání nebo překročení časového limitu jednoduše zavolejte completion handler s původním obsahem bez přílohy. Systém zobrazí notifikaci ve standardní podobě bez médií. Chyby protokolujte přes OSLog pro diagnostiku, ale neblokujte zobrazení notifikace.
Rozšíření pracuje v izolovaném procesu s limitem přibližně 50 MB. Při překročení limitu systém ukončí proces přes watchdog. Vyhněte se načítání velkých souborů, ukládání obrázků v paměti a únikům paměti při práci s URLSession.
Shrnutí
Vyvineme mobilní aplikaci na klíč
IT Sectr vytváří aplikace pro iOS a Android pro startupy a podniky od roku 2017. Poradíme vám a navrhneme nejlepší řešení.
Přečtěte si také