Notification Service Extension è un'estensione iOS che intercetta una notifica push prima che venga visualizzata all'utente e consente di modificarne il contenuto. L'estensione può decriptare dati crittografati, scaricare allegati multimediali, modificare il testo o aggiungere campi personalizzati. Secondo Apple Developer, 2025, Notification Service Extension ha fino a 30 secondi per completare l'attività in background.
Punti chiave
Notification Service Extension è un'estensione dell'app in iOS che viene eseguita prima della visualizzazione di una notifica push. Consente al server di inviare un payload minimo mentre l'estensione lo arricchisce con contenuti: scaricare immagini, decriptare dati, sostituire testo. L'utente vede la notifica già elaborata.
Quando iOS riceve una notifica push, il sistema verifica se esiste un'estensione per l'app. Se l'estensione è registrata, iOS la avvia in un processo in background e passa il contenuto della notifica tramite il metodo didReceive(_:withContentHandler:). L'estensione elabora il contenuto e chiama contentHandler con il contenuto modificato. Se l'estensione non completa entro 30 secondi, il sistema visualizza la notifica originale.
Service Extension è necessario negli scenari in cui il contenuto della notifica richiede elaborazione sul dispositivo. Comunicazioni sicure: il server invia un payload crittografato, l'estensione lo decripta localmente. Notifiche multimediali ricche: il server invia un URL di un'immagine, l'estensione la scarica e la allega. Localizzazione dinamica: l'estensione sostituisce il testo nella lingua del dispositivo.
| Scenario | Senza estensione | Con estensione |
|---|---|---|
| Immagine | Non supportato | Scaricata e visualizzata |
| Crittografia | Il server conserva la chiave | Decriptazione sul dispositivo |
| Testo | Fissato sul server | Sostituzione dinamica |
| Validazione | Non verificata | Notifiche dannose annullate |
Notification Service Extension funziona in un ambiente limitato. Il tempo massimo di esecuzione è di 30 secondi. L'estensione non ha accesso all'archiviazione principale dell'app (eccetto App Group). La dimensione dell'estensione è limitata a 50 MB. Quando il tempo viene superato, il sistema chiama contentHandler con il contenuto originale e tutte le modifiche vengono perse.
In Xcode, Notification Service Extension viene aggiunta creando un nuovo target di tipo Notification Service Extension. Xcode genera una classe modello NotificationService che eredita da UNNotificationServiceExtension, con due metodi: didReceive e serviceExtensionTimeWillExpire.
In Xcode, seleziona File → New → Target → Notification Service Extension. Inserisci un nome (ad esempio, PushNotificationService) e scegli il linguaggio Swift. Assicurati che il target sia aggiunto all'app principale e abbia la firma corretta. Dopo la creazione, verrà generata la classe NotificationService.swift con un'implementazione di base.
L'Info.plist dell'estensione contiene la chiave NSExtension con le sottochiavi NSExtensionPointIdentifier (com.apple.usernotifications.service) e NSExtensionPrincipalClass (il nome del tuo controller). Inoltre, è possibile specificare NSExtensionAttributes con le regole di attivazione dell'estensione. Xcode genera queste impostazioni automaticamente.
L'implementazione di base sovrascrive didReceive, modifica il contenuto della notifica e chiama contentHandler. Se l'elaborazione richiede troppo tempo, viene chiamato serviceExtensionTimeWillExpire, dove è necessario completare il lavoro con lo stato corrente.
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 = "[Elaborato] \(bestAttemptContent.title)"
contentHandler?(bestAttemptContent)
}
}
override func serviceExtensionTimeWillExpire() {
if let contentHandler = contentHandler,
let bestAttemptContent = bestAttemptContent {
contentHandler(bestAttemptContent)
}
}
}
Uno degli usi principali di Service Extension è decriptare il contenuto della notifica sul dispositivo. Il server invia un payload crittografato e l'estensione lo decripta utilizzando una chiave memorizzata in Keychain o App Group. Ciò garantisce che il contenuto non possa essere intercettato durante la trasmissione.
Il server crittografa il corpo della notifica utilizzando una chiave simmetrica (AES-256). La chiave di crittografia è pre-concordata tra client e server. L'estensione riceve la stringa crittografata nel campo data del payload, la decripta e la sostituisce nei campi della notifica. La chiave utente può essere ottenuta da Keychain dopo l'autenticazione.
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)
}
La chiave di decriptazione non deve essere memorizzata nel codice dell'estensione o in NSUserDefaults. Utilizza iOS Keychain con accesso tramite App Group in modo che sia l'app che l'estensione possano leggere la chiave. Utilizza Security.framework con l'algoritmo AES-256-GCM per la generazione di chiavi sul client.
L'uso più comune di Notification Service Extension è scaricare immagini, GIF e video per la visualizzazione nella notifica. Il server invia un URL di un file multimediale e l'estensione lo scarica, lo salva in una directory temporanea e crea un UNNotificationAttachment.
L'estensione riceve l'URL dell'immagine dal campo payload della notifica. Utilizzando URLSession, l'estensione scarica il file in una directory temporanea. Una volta completato il download, viene creato un UNNotificationAttachment con l'URL locale. L'allegato viene passato al contenuto modificato. iOS visualizza automaticamente l'immagine nell'interfaccia standard o in una Notification Content Extension.
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()
}
iOS supporta i seguenti formati per la visualizzazione nelle notifiche: JPEG, PNG, GIF (statici), video MPEG-4 fino a 50 MB. Per i file audio, sono supportati MP3, AAC e ALAC. Importante: tutti i file multimediali devono essere scaricati entro il limite di 30 secondi. Per file grandi, si consiglia il ritaglio lato server o il caricamento progressivo.
Gestire il limite di 30 secondi è un compito chiave nello sviluppo di Notification Service Extension. Se l'estensione non completa l'elaborazione in tempo, il sistema chiama serviceExtensionTimeWillExpire e visualizza il contenuto originale. È necessario prevedere scenari di fallback per ogni tipo di elaborazione.
Dividi le attività per priorità. Esegui prima le modifiche critiche (decriptazione, localizzazione di base). I miglioramenti opzionali (download di immagini, arricchimento del testo) vengono dopo. Utilizza URLSession con timeout per le richieste di rete per evitare di spendere l'intero limite su una singola operazione.
Se il download dell'immagine fallisce o la decriptazione del payload restituisce un errore, l'estensione deve chiamare contentHandler con il contenuto originale. Non terminare mai l'estensione senza chiamare contentHandler — ciò comporta la perdita della notifica. Un fallback sicuro deve essere sempre previsto nel codice dell'estensione.
override func didReceive(
request: UNNotificationRequest,
withContentHandler handler: @escaping (UNNotificationContent) -> Void
) {
let content = (request.content.mutableCopy()
as? UNMutableNotificationContent) ?? request.content
// Attività critica: decriptazione
var decryptedContent = tryDecryptPayload(content)
// Attività opzionale: media
guard let mediaUrl = decryptedContent.userInfo["media_url"]
as? String else {
handler(decryptedContent)
return
}
downloadAndAttachMedia(
content: decryptedContent,
mediaUrl: mediaUrl,
handler: handler
)
}
Per testare Notification Service Extension, usa Xcode: seleziona il target dell'estensione, esegui sul simulatore e invia una notifica push tramite terminale o Firebase Console. Registra ogni fase dell'elaborazione usando os_log — questo aiuta a diagnosticare problemi di temporizzazione e download.
Domande frequenti
Il sistema chiama serviceExtensionTimeWillExpire, poi visualizza la notifica originale senza modifiche. Tutti i file scaricati e le modifiche vengono scartati.
Sì, se chiami contentHandler con contenuto vuoto (UNNotificationContent con campi vuoti), la notifica non verrà visualizzata. Viene utilizzato per filtrare notifiche spam o dati errati.
Il token può essere passato nel userInfo del payload della notifica o ottenuto da Keychain tramite App Group. Non è consigliato memorizzare token in UserDefaults dell'estensione.
L'estensione deve essere firmata con lo stesso certificato di sviluppatore dell'app principale. Per la produzione, è necessario un certificato di produzione con la capacità Push Notifications abilitata.
Collega il dispositivo a Xcode, seleziona il target dell'estensione nello schema di esecuzione e invia una notifica push tramite Firebase Console. I breakpoint nell'estensione funzionano come nell'app principale.
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