Notification Extension è un meccanismo iOS che consente di modificare il contenuto e l'aspetto delle notifiche push prima che vengano visualizzate all'utente. Le estensioni operano lato sistema operativo in un processo separato: UNNotificationServiceExtension elabora il contenuto in arrivo, mentre UNNotificationContentExtension gestisce l'interfaccia. Secondo Apple Developer Documentation, 2026, la Service Extension ha fino a 30 secondi per eseguire attività prima della visualizzazione della notifica. Questo limite è critico durante il download di allegati o la decifratura dei dati.
Punti chiave
Notification Extension è un componente software iOS che estende il comportamento standard delle notifiche push aggiungendo la possibilità di modificare il contenuto e personalizzare l'interfaccia. A differenza delle notifiche ordinarie che vengono visualizzate dal sistema in un formato standard, le estensioni consentono allo sviluppatore di influenzare il contenuto prima della visualizzazione e creare un'interfaccia utente unica.
Apple fornisce due tipi di Notification Extension per scopi diversi: UNNotificationServiceExtension gestisce l'elaborazione del payload in arrivo, mentre UNNotificationContentExtension gestisce la visualizzazione. La Service Extension viene eseguita prima che la notifica venga mostrata e ha un tempo di esecuzione limitato — fino a 30 secondi secondo Apple Developer Documentation. La Content Extension si attiva dopo che l'utente interagisce con la notifica e visualizza una vista personalizzata.
Una notifica push iOS standard viene visualizzata automaticamente dal sistema in base ai campi alert, title e subtitle del payload JSON. Notification Extension intercetta il controllo: Service Extension riceve il payload grezzo, lo modifica e lo passa al sistema per la visualizzazione. Content Extension sostituisce il banner standard con un'interfaccia personalizzata con qualsiasi elemento di controllo.
Quando il dispositivo riceve una notifica push con la chiave mutable-content: 1, il sistema avvia Service Extension in un processo separato. Il processo dell'estensione è isolato dall'applicazione principale e ha la propria sandbox con un limite di memoria di 50 MB. Dopo aver completato l'elaborazione, l'estensione chiama il completion handler, passando il UNNotificationContent modificato al sistema per la visualizzazione.
UNNotificationServiceExtension è lo strumento principale per modificare programmaticamente le notifiche push prima che vengano visualizzate all'utente. L'estensione si attiva automaticamente alla ricezione di una notifica il cui payload ha il flag mutable-content: 1 impostato. In 30 secondi, l'estensione può scaricare un allegato multimediale, modificare il testo, decifrare dati crittografati o arricchire il contenuto.
L'estensione implementa due metodi chiave del protocollo UNNotificationServiceExtension. Il metodo didReceive riceve la richiesta in arrivo con il UNNotificationRequest grezzo e consente la modifica tramite il completion handler con un nuovo UNNotificationContent. Il metodo serviceExtensionTimeWillExpire viene chiamato dal sistema un secondo prima del timeout — in esso è necessario completare l'elaborazione e passare il risultato corrente (possibilmente parziale).
Considera uno scenario in cui il server invia un push con un URL di immagine in un campo personalizzato. Service Extension scarica questa immagine dalla rete, crea un UNNotificationAttachment e lo aggiunge al contenuto. UNNotificationAttachment accetta un file locale di immagine, video o audio e lo copia automaticamente nella sandbox dell'estensione. Dopo aver creato l'allegato, l'estensione passa il contenuto aggiornato al sistema.
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)
}
}
Quando le notifiche con gli stessi allegati vengono inviate frequentemente, si consiglia di memorizzare nella cache i file scaricati sul dispositivo. FileManager fornisce l'accesso alla directory cache dell'estensione, che persiste tra le esecuzioni. Ciò riduce il tempo di elaborazione delle notifiche successive e diminuisce il carico di rete. Secondo Apple, la cache può ridurre il tempo di elaborazione a 2–5 secondi invece di un download completo.
UNNotificationContentExtension consente di sostituire il banner di notifica standard con un'interfaccia personalizzata creata in Interface Builder o SwiftUI. L'estensione si attiva quando l'utente esegue un'azione sulla notifica: tocco, scorrimento verso il basso o 3D Touch. Content Extension riceve il contenuto già elaborato da Service Extension e lo visualizza in una vista personalizzata.
Ogni Content Extension è collegata a una o più categorie di notifica tramite Info.plist. La categoria viene definita sul server dal campo category nel payload APNS. Il sistema seleziona automaticamente l'estensione appropriata in base alla categoria della notifica ricevuta. L'interfaccia viene costruita tramite storyboard utilizzando componenti UIKit standard o SwiftUI View.
Content Extension supporta pulsanti personalizzati e gestori di tocco definiti in UNNotificationAction. UNNotificationAction viene creato nella fase di registrazione della categoria e può supportare l'input di testo tramite UNTextInputNotificationAction. Quando l'utente preme un pulsante, l'estensione riceve il callback didReceive con l'identificatore dell'azione e può eseguire la logica corrispondente — aprire un URL, inviare una richiesta al server o aggiornare l'interfaccia.
Content Extension viene eseguita in un processo isolato con il proprio ciclo di esecuzione e un limite di memoria di circa 50 MB. Le prestazioni dell'estensione sono critiche perché il watchdog del sistema termina il processo quando i limiti vengono superati. Si consiglia di evitare calcoli pesanti, caricamento di immagini grandi e richieste di rete prolungate all'interno di Content Extension.
UNNotificationAttachment è un oggetto che aggiunge un file multimediale a una notifica push: immagine, video, audio o GIF. L'allegato viene creato da un URL di file locale che deve trovarsi nella sandbox dell'estensione. La dimensione massima dell'allegato non deve superare i 10 MB, altrimenti il sistema rifiuterà l'allegato al momento della creazione.
Apple supporta un insieme limitato di formati per gli allegati multimediali. Immagini — JPEG, PNG, GIF (incluse animate), TIFF. Video — MPEG, MP4, MOV con durata massima di 30 secondi. Audio — MP3, AAC, WAV, CAF. Per ogni formato è possibile specificare il tipo tramite UNNotificationAttachmentOptionsTypeHintKey, che aiuta il sistema a elaborare correttamente il file.
Poiché il payload push contiene solo un URL, non il file stesso, il download dell'allegato deve essere eseguito all'interno di Service Extension. Il tempo massimo di download è limitato a 30 secondi, pertanto si consiglia di utilizzare URLSession con impostazioni minime e disabilitare il download in caso di segnale debole. Se l'allegato non viene caricato in tempo, la notifica viene visualizzata senza multimedia — questo è il comportamento predefinito del sistema.
Esaminiamo un esempio completo di Notification Extension che scarica un'immagine, la salva e la aggiunge alla notifica. NotificationService eredita da UNNotificationServiceExtension e sovrascrive il metodo didReceive. L'esempio mostra la gestione dei campi opzionali, la creazione dell'allegato e la chiamata al completion handler con contenuto modificato.
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)
}
}
}
Affinché l'estensione funzioni correttamente, è necessario registrare le categorie di notifica in Info.plist. La chiave NSExtensionPointIdentifier viene impostata su com.apple.usernotifications.service per Service Extension o com.apple.usernotifications.content per Content Extension. Le categorie vengono definite in AppDelegate all'avvio dell'applicazione tramite UNUserNotificationCenter e l'estensione si attiva solo per le notifiche con una categoria corrispondente nel payload.
Domande frequenti
Service Extension modifica il contenuto prima della visualizzazione della notifica — aggiunge media, cambia il testo, decifra i dati. Content Extension sostituisce l'interfaccia della notifica con una personalizzata dopo l'interazione dell'utente. Service Extension funziona prima della visualizzazione, Content Extension dopo.
Il sistema alloca 30 secondi per l'esecuzione del codice in didReceive. Se l'elaborazione non viene completata entro questo tempo, viene chiamato serviceExtensionTimeWillExpire, dove è necessario passare il risultato corrente. Si consiglia di rimanere entro 10–15 secondi considerando i download degli allegati.
Sì, SwiftUI è supportato in Content Extension a partire da iOS 16. La View viene incapsulata in un UIHostingController e aggiunta allo storyboard. Tuttavia, a causa dei limiti di memoria, si consiglia di utilizzare SwiftUI solo per interfacce semplici con un numero minimo di elementi.
In caso di errore di download o timeout, chiama semplicemente il completion handler con il contenuto originale senza allegato. Il sistema visualizzerà la notifica in formato standard senza media. Registra gli errori tramite OSLog per la diagnostica, ma non bloccare la visualizzazione della notifica.
L'estensione viene eseguita in un processo isolato con un limite di circa 50 MB. Quando superato, il sistema termina il processo tramite watchdog. Evita di caricare file grandi, memorizzare immagini in memoria e perdite quando lavori con URLSession.
Riepilogo
Svilupperemo un'applicazione mobile chiavi in mano
IT Sectr crea applicazioni iOS e Android per startup e aziende dal 2017. Ti consulteremo e ti proporremo la soluzione migliore.
Leggi anche