Notification Service Extension — cum funcționează procesarea notificărilor

Autor: IT Sectr Publicat: 2026-06-16 Timp de citire: 9 min

Notification Service Extension este o extensie iOS care interceptează notificarea push imediat după primire, dar înainte de afișarea către utilizator. Extensia poate decripta payload-ul criptat, poate descărca și atașa un fișier media, poate modifica textul sau titlul notificării în timp real. Conform Apple Developer Documentation (2025), pentru activarea extensiei, serverul trebuie să trimită cheia mutable-content:1 în atributele notificării — aceasta este singura condiție pentru pornirea UNNotificationServiceExtension.

Principalele puncte

  • Notification Service Extension modifică notificarea push înainte de afișarea ei utilizatorului pe dispozitivul iOS
  • Pentru activarea extensiei este necesar parametrul mutable-content:1 în payload-ul notificării de la server
  • Protocolul principal — UNNotificationServiceExtension cu metodele didReceive(_:withContentHandler:) și serviceExtensionTimeWillExpire()
  • Extensia poate descărca atașamente media din rețea și le poate atașa la notificare prin UNNotificationAttachment
  • Timpul de execuție este limitat — sistemul alocă aproximativ 30 de secunde pentru procesarea completă a unei notificări

Ce este Notification Service Extension

Notification Service Extension este o extensie de aplicație în iOS care interceptează notificarea push primită pe dispozitiv și permite modificarea conținutului său înainte ca utilizatorul să o vadă. Este singurul tip de extensie de notificări care lucrează cu conținutul, nu cu afișarea.

Diferența cheie față de Notification Content Extension: Service Extension funcționează înainte de afișarea notificării și poate modifica titlul, corpul, fișierul sonor și atașamentele. Content Extension funcționează după afișare și gestionează doar prezentarea vizuală a notificării finale. Aceste două extensii pot lucra împreună: Service Extension descarcă imaginea, iar Content Extension o afișează într-o interfață personalizată.

Extensia se activează automat la primirea unei notificări push cu atributul mutable-content:1 în dicționarul aps. iOS pornește extensia în fundal, îi transmite UNNotificationRequest original și așteaptă versiunea modificată pentru afișare.

Procesarea notificărilor push pe loc

UNNotificationServiceExtension primește UNNotificationRequest complet cu conținutul original. Extensia poate modifica orice câmp UNNotificationContent: title, subtitle, body, userInfo, attachments și sound. Modificările se aplică înainte ca notificarea să fie afișată.

Scenarii tipice de utilizare

Decriptarea conținutului — dacă notificarea push conține un payload criptat, extensia îl decriptează înainte de afișare. Descărcarea media — atașarea unei imagini sau a unui videoclip la notificare. Localizarea — adaptarea textului notificării la setările regionale ale dispozitivului. Îmbogățirea datelor — adăugarea de informații suplimentare din stocarea locală sau cache.

Conform Apple, cel mai frecvent scenariu printre aplicații este descărcarea imaginilor pentru notificări media bogate. Serverul trimite URL-ul imaginii în payload, extensia o descarcă într-un director temporar și creează UNNotificationAttachment pe care sistemul îl afișează în interfața standard sau personalizată.

Modificarea textului și a titlului

Extensia poate rescrie complet textul notificării, poate înlocui titlul sau poate adăuga un subtitle. De exemplu, o aplicație de mesagerie poate primi o notificare criptată, o poate decripta în extensie și poate afișa text lizibil. Sau o aplicație de știri poate adăuga categoria știrii în subtitlu înainte de afișare.

swift
override func didReceive(
    _ request: UNNotificationRequest,
    withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void
) {
    let content = request.content.mutableCopy()
        as! UNMutableNotificationContent
    if let imageURL = content.userInfo["media-url"]
        as? String {
        downloadAndAttach(imageURL: imageURL,
            content: content,
            handler: contentHandler)
    }
}

Protocolul UNNotificationServiceExtension

UNNotificationServiceExtension — clasa de bază de la care moștenește Service Extension. Clasa definește două metode ale ciclului de viață: didReceive(_:withContentHandler:) — metoda principală de procesare, și serviceExtensionTimeWillExpire() — handlerul pentru expirarea timpului.

Metoda didReceive:withContentHandler:

didReceive(_:withContentHandler:) este apelată la primirea notificării. Extensia primește UNNotificationRequest și closure-ul contentHandler care trebuie apelat cu UNMutableNotificationContent modificat. Extensia este obligată să apeleze contentHandler — dacă nu o face, iOS va afișa notificarea originală după expirarea timeout-ului.

Important: extensia poate procesa o singură notificare odată. Dacă sosesc mai multe notificări simultan, iOS creează instanțe separate ale extensiei pentru fiecare. Nu se poate utiliza starea globală pentru procesarea secvențială.

Metoda serviceExtensionTimeWillExpire:

serviceExtensionTimeWillExpire() este apelată de sistem când timpul rămas de execuție se apropie de sfârșit. În această metodă, trebuie apelat imediat contentHandler cu conținutul care este gata în acel moment — chiar dacă fișierul media nu s-a descărcat încă. Dacă contentHandler nu este apelat în această metodă, iOS va afișa notificarea originală.

Se recomandă păstrarea în această metodă a unui conținut minim acceptabil — de exemplu, o notificare cu text și titlu, dar fără imaginea a cărei descărcare nu s-a finalizat la timp.

Criptarea și atașamentele media

UNNotificationAttachment — un obiect creat de extensie pentru a atașa un fișier media la notificare. Extensia descarcă fișierul din rețea, îl salvează într-un director temporar și creează UNNotificationAttachment cu specificarea tipului de conținut.

Crearea unui atașament dintr-un fișier descărcat

UNNotificationAttachment se creează cu ajutorul inițializatorului init(identifier:url:options:). URL-ul trebuie să indice un fișier local în directorul temporar accesibil extensiei. După creare, atașamentul se adaugă în tabloul attachments al UNMutableNotificationContent.

Apple recomandă utilizarea URLSession cu configurare de fundal pentru descărcare — la utilizarea URLSession standard, descărcarea blochează firul de execuție și consumă timp din limita de 30 de secunde. URLSession de fundal continuă descărcarea chiar și după terminarea extensiei, iar rezultatul poate fi folosit la următoarea pornire.

Decriptarea payload-ului criptat

Dacă serverul trimite o notificare criptată, extensia trebuie să decripteze payload-ul înainte de a apela contentHandler. Decriptarea include de obicei solicitarea cheii din Keychain sau App Group, decriptarea prin CommonCrypto și înlocuirea body sau userInfo al notificării. În caz de eroare de decriptare, trebuie apelat contentHandler cu conținutul original — pentru ca utilizatorul să vadă măcar că notificarea a sosit, chiar dacă este ilizibilă.

swift
func downloadAndAttach(
    imageURL: String,
    content: UNMutableNotificationContent,
    handler: @escaping (UNNotificationContent) -> Void
) {
    let task = URLSession.shared.dataTask(with:
        URL(string: imageURL)!) { data, _, _ in
        let url = FileManager.default
            .temporaryDirectory
            .appendingPathComponent("image.jpg")
        try? data?.write(to: url)
        let attachment = try? UNNotificationAttachment(
            identifier: "image", url: url)
        content.attachments = [attachment].compactMap { $0 }
        handler(content)
    }
    task.resume()
}

Timeout-uri și mecanisme de fallback

Notification Service Extension funcționează în limite de timp stricte. iOS alocă un timp fix de execuție — aproximativ 30 de secunde de la momentul activării. Dacă extensia nu apelează contentHandler în acest timp, sistemul forțează încheierea procesului și afișează notificarea originală fără modificări.

Strategia de graceful degradation

Se recomandă implementarea unui fallback pe mai multe niveluri: mai întâi încercați să descărcați media, la succes — apelați contentHandler cu conținutul complet; la eșec — apelați contentHandler cu textul, dar fără media; la eroare critică — transmiteți conținutul original. Această abordare garantează că utilizatorul va vedea întotdeauna o notificare, nu un ecran gol.

Conform Apple, cea mai frecventă cauză a timeout-urilor este descărcarea fișierelor media mari la conexiune lentă. Pentru reducerea riscului, se recomandă optimizarea dimensiunii imaginilor pe server — trimiterea de previzualizări de până la 300 KB în loc de rezoluție completă. Imaginile la rezoluție completă ar trebui descărcate la deschiderea aplicației.

Monitorizarea performanței

Pentru urmărirea timeout-urilor și erorilor extensiei se poate utiliza os_log pentru înregistrarea mesajelor de diagnostic în Unified Logging System. Deși înregistrarea directă în fișier în extensie este dificilă, os_log permite analizarea performanței prin Console.app pe dispozitivul de dezvoltare. Apple recomandă adăugarea de metrici la fiecare apel didReceive — timpul de descărcare, dimensiunea fișierului, rezultatul operațiunii.

swift
override func serviceExtensionTimeWillExpire() {
    let fallback = bestEffortContent as?
        UNMutableNotificationContent
        ?? request.content.mutableCopy()
        as! UNMutableNotificationContent
    contentHandler(fallback)
}

Întrebări frecvente

Cum activează serverul Notification Service Extension?

Serverul adaugă cheia mutable-content:1 în dicționarul aps al notificării push. Fără acest parametru, sistemul ignoră extensia și afișează notificarea standard.

Se poate folosi extensia fără mutable-content?

Nu. mutable-content:1 este o condiție obligatorie pentru activarea Service Extension. Dacă cheia lipsește sau este setată la 0, notificarea se afișează fără apelarea extensiei.

Ce se întâmplă la depășirea limitei de 30 de secunde?

iOS forțează încheierea extensiei și afișează notificarea originală fără modificări. Pentru a evita acest lucru, implementați serviceExtensionTimeWillExpire() cu un conținut minim acceptabil.

Cum se transmit cheile de criptare în extensie?

Prin App Group (UserDefaults sau fișier partajat) sau Keychain cu acces partajat între aplicație și extensie. Transmiterea directă a cheilor în payload-ul notificării este nesigură.

Câte fișiere media se pot atașa în Service Extension?

Până la 4 atașamente per notificare, fiecare de până la 50 MB. Dimensiunea totală a atașamentelor influențează timpul de descărcare — cu cât mai multe fișiere, cu atât riscul de timeout este mai mare.

Concluzii

  • Notification Service Extension modifică notificările push pe dispozitiv înainte de afișare, editând textul, titlul și atașamentele media
  • Pentru activare este necesară cheia mutable-content:1 în dicționarul aps — fără ea extensia nu pornește
  • Protocolul principal UNNotificationServiceExtension definește metodele didReceive și serviceExtensionTimeWillExpire pentru procesare
  • Extensia poate descărca media din rețea, decripta payload-ul și adăuga până la 4 atașamente la notificare
  • Timpul de execuție este limitat la aproximativ 30 de secunde — la depășire iOS afișează notificarea originală
  • Se recomandă strategia de graceful degradation cu fallback pe mai multe niveluri pentru a preveni notificările goale

Vom dezvolta o aplicație mobilă la cheie

IT Sectr creează aplicații iOS și Android pentru startup-uri și afaceri din 2017. Vă vom consilia și vă vom propune cea mai bună soluție.

Discutați proiectul

Citiți și