Notification Service Extension: zpracování obsahu před zobrazením na iOS

Autor: IT Sectr Publikováno: 2026-03-21 Doba čtení: 8 min

Notification Service Extension — je iOS rozšíření, které zachytí push oznámení před jeho zobrazením uživateli a umožňuje upravit obsah. Rozšíření může dešifrovat zašifrovaná data, stáhnout multimediální přílohy, změnit text nebo přidat vlastní pole. Podle Apple Developer, 2025Notification Service Extension až 30 sekund na provedení úlohy na pozadí.

Hlavní

  • Notification Service Extension — iOS rozšíření pro zpracování push oznámení před zobrazením.
  • Rozšíření dědí z UNNotificationServiceExtension a implementuje metodu didReceive.
  • Až 30 sekund běhu na pozadí pro stažení a zpracování dat.
  • Hlavní scénáře: dešifrování payloadu, stažení obrázků a videí, validace obsahu.
  • Rozšíření může zpozdit zobrazení oznámení nebo jej zcela zrušit prostřednictvím contentHandler.

Co je Notification Service Extension

Notification Service Extension — je rozšíření aplikace v iOS, které se spouští před zobrazením push oznámení. Umožňuje serveru odeslat minimální payload a rozšíření jej doplnit obsahem: stáhnout obrázky, dešifrovat data, nahradit text. Uživatel vidí hotové, zpracované oznámení.

Jak to funguje

Když iOS obdrží push oznámení, systém zkontroluje přítomnost rozšíření pro tuto aplikaci. Pokud je rozšíření zaregistrováno, iOS jej spustí v procesu na pozadí a předá obsah oznámení prostřednictvím metody didReceive(_:withContentHandler:). Rozšíření zpracuje obsah a zavolá contentHandler s upraveným obsahem. Pokud rozšíření nestihne práci do 30 sekund, systém zobrazí původní oznámení.

Kdy použít Service Extension

Service Extension je nezbytný ve scénářích, kde obsah oznámení vyžaduje zpracování na zařízení. Bezpečná komunikace: server odešle zašifrovaný payload, rozšíření jej lokálně dešifruje. Bohatá multimediální oznámení: server odešle URL obrázku, rozšíření jej stáhne a připojí. Dynamická lokalizace: rozšíření nahradí text v jazyce zařízení.

ScénářBez rozšířeníS rozšířením
ObrázekNení podporovánoStahuje se a zobrazuje
ŠifrováníServer uchovává klíčDešifrování na zařízení
TextPevně nastaven na serveruDynamické nahrazení
ValidaceNekontroluje seZrušení škodlivých oznámení

Omezení a doba běhu

Notification Service Extension pracuje v omezeném prostředí. Maximální doba běhu — 30 sekund. Rozšíření nemá přístup k hlavnímu úložišti aplikace (kromě App Group). Velikost rozšíření je omezena na 50 MB. Při překročení času systém zavolá contentHandler s původním obsahem a všechny změny jsou ztraceny.

Vytvoření rozšíření a konfigurace Info.plist

V Xcode se Notification Service Extension přidá vytvořením nového targetu typu Notification Service Extension. Xcode vygeneruje šablonu třídy NotificationService dědící z UNNotificationServiceExtension se dvěma metodami: didReceive a serviceExtensionTimeWillExpire.

Přidání targetu do projektu

V Xcode zvolte File → New → Target → Notification Service Extension. Zadejte název (např. PushNotificationService) a jazyk Swift. Ujistěte se, že target byl přidán k hlavní aplikaci a má správný podpis. Po vytvoření bude vygenerována třída NotificationService.swift se základní implementací.

Struktura Info.plist rozšíření

Info.plist rozšíření obsahuje klíč NSExtension s podklíči NSExtensionPointIdentifier (com.apple.usernotifications.service) a NSExtensionPrincipalClass (název vašeho kontroleru). Volitelně lze zadat NSExtensionAttributes s pravidly aktivace rozšíření. Tato nastavení Xcode generuje automaticky.

Příklad základního rozšíření

Základní implementace přepíše didReceive, upraví obsah oznámení a zavolá contentHandler. Pokud zpracování trvá příliš dlouho, je zavolána serviceExtensionTimeWillExpire, kde je třeba dokončit práci s aktuálním stavem.

swift
import UserNotifications

class NotificationService: UNNotificationServiceExtension {

    var contentHandler: ((UNNotificationContent) -> Void)?
    var bestAttemptContent: UNMutableNotificationContent?

    override func didReceive(
        request: UNNotificationRequest,
        withContentHandler handler: @escaping (UNNotificationContent) -> Void
    ) {
        contentHandler = handler
        bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent)

        if let bestAttemptContent = bestAttemptContent {
            bestAttemptContent.title = "[Zpracováno] \(bestAttemptContent.title)"
            contentHandler?(bestAttemptContent)
        }
    }

    override func serviceExtensionTimeWillExpire() {
        if let contentHandler = contentHandler,
           let bestAttemptContent = bestAttemptContent {
            contentHandler(bestAttemptContent)
        }
    }
}

Dešifrování zašifrovaného payloadu

Jedním z klíčových použití Service Extension je dešifrování obsahu oznámení na zařízení. Server odešle zašifrovaný payload a rozšíření jej dešifruje pomocí klíče uloženého v Keychain nebo App Group. To zaručuje, že obsah není přístupný pro zachycení během přenosu.

Architektura bezpečného doručení

Server zašifruje tělo oznámení pomocí symetrického klíče (AES-256). Šifrovací klíč je předem dohodnut mezi klientem a serverem. Rozšíření obdrží zašifrovaný řetězec v poli data payloadu, dešifruje jej a vloží do polí oznámení. Uživatelský klíč lze získat z Keychain po autentizaci.

swift
override func didReceive(
    request: UNNotificationRequest,
    withContentHandler handler: @escaping (UNNotificationContent) -> Void
) {
    guard let content = request.content.mutableCopy()
        as? UNMutableNotificationContent else {
        handler(request.content)
        return
    }

    guard let encryptedData = content.userInfo["encrypted_data"]
        as? String else {
        handler(content)
        return
    }

    let decrypted = CryptoService.decrypt(encryptedData)
    content.body = decrypted.body
    content.title = decrypted.title
    handler(content)
}

Bezpečné ukládání klíčů

Klíč k dešifrování by neměl být uložen v kódu rozšíření nebo NSUserDefaults. Použijte iOS Keychain s přístupem přes App Group, aby jak aplikace, tak rozšíření mohly klíč číst. Pro generování klíče na straně klienta použijte Security.framework s algoritmem AES-256-GCM.

Stažení a připojení multimediálních příloh

Nejčastější použití Notification Service Extension — stažení obrázků, GIFů a videí pro následné zobrazení v oznámení. Server odešle URL mediálního souboru, rozšíření jej stáhne, uloží do dočasného adresáře a vytvoří UNNotificationAttachment.

Proces stažení a připojení médií

Rozšíření obdrží URL obrázku z pole payload oznámení. Pomocí URLSession rozšíření stáhne soubor do dočasného adresáře. Po dokončení stažení je vytvořen UNNotificationAttachment s lokálním URL. Příloha je předána upravenému obsahu. iOS automaticky zobrazí obrázek ve standardním rozhraní nebo v Notification Content Extension.

swift
private func downloadAndAttachMedia(
    content: UNMutableNotificationContent,
    mediaUrl: String,
    handler: @escaping (UNNotificationContent) -> Void
) {
    guard let url = URL(string: mediaUrl) else {
        handler(content)
        return
    }

    let task = URLSession.shared.downloadTask(with: url) { localUrl, _, error in
        guard let localUrl = localUrl, error == nil else {
            handler(content)
            return
        }

        let attachment = try? UNNotificationAttachment(
            identifier: "media",
            url: localUrl,
            options: nil
        )

        if let attachment = attachment {
            content.attachments = [attachment]
        }
        handler(content)
    }
    task.resume()
}

Podporované multimediální formáty

iOS podporuje následující formáty pro zobrazení v oznámeních: JPEG, PNG, GIF (statické), MPEG-4 video do 50 MB. Pro zvukové soubory jsou podporovány MP3, AAC a ALAC. Důležité: všechny mediální soubory musí být staženy v rámci 30sekundového limitu. Pro velké soubory se doporučuje ořezání na serveru nebo progresivní stahování.

Správa času a záložní scénáře

Správa 30sekundového limitu — klíčový úkol při vývoji Notification Service Extension. Pokud rozšíření nestihne dokončit zpracování, systém zavolá serviceExtensionTimeWillExpire a zobrazí původní obsah. Pro každý typ zpracování je třeba předvídat záložní scénáře.

Strategie priorit

Rozdělte úkoly podle priorit. Kritické úpravy (dešifrování, základní lokalizace) provádějte jako první. Volitelná vylepšení (stažení obrázků, obohacení textu) — jako druhé. Pro síťové požadavky používejte URLSession s timeouty, abyste nevyčerpali celý limit na jednu operaci.

Záložní scénáře při chybách

Pokud se stažení obrázku nezdařilo nebo dešifrování payloadu vrátilo chybu, rozšíření by mělo zavolat contentHandler s původním obsahem. Nikdy neukončujte rozšíření bez zavolání contentHandler — to vede ke ztrátě oznámení. Bezpečný fallback by měl být vždy předvídán v kódu rozšíření.

swift
override func didReceive(
    request: UNNotificationRequest,
    withContentHandler handler: @escaping (UNNotificationContent) -> Void
) {
    let content = (request.content.mutableCopy()
        as? UNMutableNotificationContent) ?? request.content

    // Kritický úkol: dešifrování
    var decryptedContent = tryDecryptPayload(content)

    // Volitelný úkol: média
    guard let mediaUrl = decryptedContent.userInfo["media_url"]
        as? String else {
        handler(decryptedContent)
        return
    }

    downloadAndAttachMedia(
        content: decryptedContent,
        mediaUrl: mediaUrl,
        handler: handler
    )
}

Testování rozšíření

Pro testování Notification Service Extension použijte Xcode: vyberte target rozšíření, spusťte na simulátoru a odešlete push oznámení přes terminál nebo Firebase Console. Logujte každou fázi zpracování pomocí os_log — to pomáhá diagnostikovat problémy s časováním a chyby načítání.

Často kladené otázky

Co se stane, když rozšíření nestihne 30 sekund?

Systém zavolá serviceExtensionTimeWillExpire, poté zobrazí původní oznámení beze změn. Všechny stažené soubory a úpravy budou zahozeny.

Lze zrušit zobrazení oznámení z rozšíření?

Ano, pokud zavoláte contentHandler s prázdným obsahem (UNNotificationContent s prázdnými poli), oznámení nebude zobrazeno. Používá se k filtrování spamových oznámení nebo nesprávných dat.

Jak předat autorizační token pro stahování médií?

Token lze předat v userInfo payloadu oznámení nebo získat z Keychain přes App Group. Ukládání tokenů v UserDefaults rozšíření se nedoporučuje.

Je vyžadována speciální konfigurace certifikátů pro rozšíření?

Rozšíření musí být podepsáno stejným vývojářským certifikátem jako hlavní aplikace. Pro produkci je vyžadován produkční certifikát s povolenou capability Push Notifications.

Jak ladit rozšíření na skutečném zařízení?

Připojte zařízení k Xcode, vyberte target rozšíření ve schématu spuštění a odešlete push oznámení přes Firebase Console. Breakpoints v rozšíření fungují stejně jako v hlavní aplikaci.

Shrnutí

  • Notification Service Extension — iOS rozšíření pro zpracování push oznámení na pozadí před zobrazením.
  • Maximální doba běhu — 30 sekund, poté systém zobrazí původní obsah.
  • Hlavní použití: dešifrování payloadu, stažení médií, validace a lokalizace obsahu.
  • Rozšíření dědí z UNNotificationServiceExtension s metodami didReceive a serviceExtensionTimeWillExpire.
  • Pro stažení médií použijte URLSession, pro ukládání klíčů iOS Keychain.
  • Vždy předvídejte fallback — zavolejte contentHandler s původním obsahem při chybách.
  • Kombinujte Service Extension s Content Extension pro plnou kontrolu nad oznámeními.

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í.

Prodiskutovat projekt

Přečtěte si také