Notification Payload è una struttura JSON che il server invia tramite APNS a un dispositivo iOS, definendo il contenuto di una notifica push e il comportamento al momento della ricezione. Il payload include chiavi obbligatorie e opzionali che controllano testo, suono, badge, allegati multimediali e l’elaborazione in background. Secondo Apple Developer Documentation, 2026, la dimensione massima del payload è di 4096 byte per le notifiche normali e 5120 byte per le VoIP push, imponendo limiti rigorosi alla quantità di dati trasferiti.
Punti Chiave
Notification Payload è un oggetto JSON che il server invia ad APNS (Apple Push Notification Service) per la consegna a un dispositivo iOS. Il payload contiene tutti i dati necessari al sistema per visualizzare la notifica: titolo, testo, suono, badge e metadati per l’elaborazione in background. La struttura del payload è strettamente regolamentata da Apple e include chiavi obbligatorie per una corretta elaborazione da parte del sistema.
Quando il server invia una notifica push attraverso l’API HTTP/2 di APNS, la richiesta contiene intestazioni di autorizzazione e un corpo JSON — il payload. APNS convalida il payload: se il JSON non è valido o supera il limite di dimensione, il server Apple restituisce un errore 400 Bad Request. Dopo la convalida, APNS consegna il payload al dispositivo, dove iOS lo analizza e determina come gestire la notifica — mostrare un banner, eseguire un’attività in background o riprodurre un suono.
Il formato del payload APNS si è evoluto da un semplice payload testuale in iOS 2 a una struttura JSON multicomponente nelle versioni moderne. iOS 10 ha introdotto il supporto per gli allegati multimediali tramite mutable-content, iOS 12 ha aggiunto il raggruppamento delle notifiche tramite thread-id, e iOS 15 ha introdotto supports-live-activities per le Live Activities. Oggi, un payload può contenere fino a 15 chiavi diverse a seconda del comportamento desiderato della notifica.
L’oggetto radice del payload contiene un dizionario aps e campi personalizzati opzionali al livello superiore. Il dizionario aps è l’unico elemento obbligatorio, ma al suo interno possono apparire diverse combinazioni di chiavi a seconda del tipo di notifica: alert, badge, sound, content-available, mutable-content, interruption-level e altre.
| Chiave aps | Tipo | Scopo |
|---|---|---|
| alert | String o Dictionary | Testo della notifica o oggetto con title, subtitle, body e localizzazione |
| badge | Number | Numero sull’icona dell’app; 0 rimuove il badge |
| sound | String | Nome del file audio o default per il suono di sistema |
| content-available | Number (1) | Flag di attivazione in background; 1 = silent push |
| mutable-content | Number (1) | Flag di attivazione dell’estensione di servizio per modificare il contenuto |
| category | String | Identificatore di categoria per pulsanti ed estensione di contenuto |
| thread-id | String | Identificatore di gruppo per il raggruppamento delle notifiche |
| interruption-level | String | Livello di interruzione: passive, active, time-sensitive, critical |
| relevance-score | Number (0–1) | Priorità della notifica per il sistema di classificazione intelligente |
La chiave alert può essere una semplice stringa (che diventa il corpo della notifica) o un dizionario con i campi title, subtitle e body. Il formato dizionario consente di impostare titolo e sottotitolo separatamente dal testo principale. Per le notifiche localizzate, vengono utilizzate le chiavi title-loc-key, title-loc-args, loc-key e loc-args, che fanno riferimento al Localizable.strings dell’app. Ciò consente di inviare un payload senza testo in una lingua specifica — l’app sostituisce la traduzione.
A partire da iOS 15, Apple ha introdotto il meccanismo Focus Mode, che richiede allo sviluppatore di specificare il livello di interruzione della notifica. interruption-level accetta i valori: passive (nessun suono, nessun risveglio dello schermo), active (comportamento standard), time-sensitive (attraversa il Focus, richiede autorizzazione speciale) e critical (situazioni mediche/di emergenza). La chiave relevance-score (0–1) aiuta il sistema Focus a classificare le notifiche all’interno di una stessa categoria.
La chiave thread-id raggruppa le notifiche nel Centro Notifiche. Tutte le notifiche con lo stesso thread-id vengono visualizzate come un unico gruppo che l’utente può espandere. Ciò è particolarmente utile per i messenger, dove i messaggi di un contatto vengono raggruppati insieme, o per le app che inviano molte notifiche dello stesso tipo.
I campi personalizzati sono tutte le chiavi al di fuori del dizionario aps che lo sviluppatore aggiunge per trasmettere dati aggiuntivi al dispositivo. Il server li include nell’oggetto JSON radice del payload e l’app li recupera tramite userInfo in UNNotificationContent. I campi personalizzati non devono duplicare i nomi delle chiavi di aps per evitare conflitti durante l’analisi.
La limitazione principale è che la dimensione totale del payload non deve superare i 4096 byte. I campi personalizzati competono per questo limite con le chiavi obbligatorie di aps, quindi è importante ridurre al minimo la dimensione dei dati trasmessi. Utilizza nomi di chiave brevi (ad esempio, “uid” invece di “user-id”), evita strutture JSON grandi e trasmetti solo identificatori invece di oggetti dati completi.
I campi personalizzati provengono dal server e non dovrebbero essere considerati affidabili senza verifica. Convalida sempre i tipi e i valori dei campi personalizzati durante l’analisi: verifica l’esistenza della chiave tramite binding opzionale, converti con as? String/Int/Dictionary nel tipo previsto e gestisci il caso di valore assente. Non utilizzare mai force unwrap (!) per i dati del payload — il server potrebbe inviare dati non validi e l’app potrebbe bloccarsi.
{
"aps": {
"alert": {
"title": "Nuovo messaggio",
"body": "Ciao! Come stai?"
},
"badge": 5,
"sound": "default",
"category": "message",
"thread-id": "chat_4521",
"mutable-content": 1
},
"sender-id": "user_789",
"chat-id": "chat_4521",
"message-type": "text",
"image-url": "https://cdn.example.com/img.jpg"
}
Utilizza uno stile di denominazione coerente per i campi personalizzati in tutti i payload del progetto. kebab-case (message-type) o camelCase (messageType) — entrambi gli approcci sono accettabili, ma la coerenza all’interno del progetto è importante. Evita nomi lunghi: “uid” invece di “user-identifier”, “img” invece di “profile-image-url”. Ogni carattere in un nome di chiave consuma un byte del limite di 4096.
Scenari diversi di notifiche push richiedono diverse combinazioni di chiavi nel payload. Esaminiamo diversi esempi tipici: una notifica di testo semplice, una notifica localizzata, un Silent Push e una Rich Notification con allegato multimediale.
Un payload di base con testo e suono — la configurazione minima per visualizzare una notifica all’utente. Alert come stringa fornisce un messaggio breve, sound default riproduce il suono di sistema standard. Badge è opzionale e imposta il contatore sull’icona dell’app. category e thread-id vengono aggiunti per raggruppamento e interattività.
{
"aps": {
"alert": "Promemoria: riunione tra 15 minuti",
"badge": 3,
"sound": "default"
}
}
Per inviare notifiche a dispositivi con lingue diverse, utilizza chiavi di localizzazione invece di testo fisso. title-loc-key fa riferimento a una chiave nel Localizable.strings dell’app e title-loc-args fornisce argomenti. Ciò consente di inviare un unico payload a tutti i dispositivi e l’app mostra il testo nella lingua appropriata.
{
"aps": {
"alert": {
"title-loc-key": "NEW_MESSAGE_TITLE",
"title-loc-args": ["Anna"],
"loc-key": "NEW_MESSAGE_BODY",
"loc-args": ["Ciao!"]
},
"sound": "message.caf"
}
}
Per la sincronizzazione in background senza mostrare una notifica, utilizza content-available: 1 senza alert. I campi personalizzati specificano il tipo di operazione e i dati per l’elaborazione. Il sistema attiva l’app in background, chiama didReceiveRemoteNotification con fetchCompletionHandler e l’app esegue la sincronizzazione.
{
"aps": {
"content-available": 1
},
"sync-type": "invalidate-cache",
"timestamp": "2026-07-03T12:00:00Z"
}
Per visualizzare un allegato multimediale, è necessario mutable-content: 1 per attivare l’estensione di servizio, insieme a un URL dell’immagine in un campo personalizzato. mutable-content: 1 segnala al sistema di avviare UNNotificationServiceExtension, che scarica l’immagine dall’URL e la aggiunge come UNNotificationAttachment. La chiave category specifica una categoria registrata per visualizzare i pulsanti di azione.
{
"aps": {
"alert": {
"title": "Nuovo prodotto",
"body": "Scopri la nuova collezione"
},
"category": "product",
"mutable-content": 1
},
"media-url": "https://cdn.example.com/product.jpg"
}
UNNotificationContent.userInfo contiene il dizionario completo del payload ricevuto dopo l’elaborazione del sistema. L’app accede al payload nel delegato UNUserNotificationCenter quando riceve una notifica (in primo piano), quando tocca una notifica, oltre che nell’estensione di servizio e nell’estensione di contenuto. Un parsing corretto è essenziale per estrarre i dati personalizzati e determinare le azioni successive.
Quando l’utente tocca una notifica, il sistema chiama il metodo didReceive response in UNUserNotificationCenterDelegate. response.notification.request.content.userInfo contiene il payload completo. Lo sviluppatore estrae i campi personalizzati, determina il tipo di azione (ad esempio, aprire una chat, navigare verso un prodotto) e attiva la navigazione corrispondente nell’app.
func userNotificationCenter(
_ center: UNUserNotificationCenter,
didReceive response: UNNotificationResponse,
withCompletionHandler completionHandler: @escaping () -> Void
) {
let userInfo = response.notification
.request.content.userInfo
guard let chatId = userInfo["chat-id"] as? String
else {
completionHandler()
return
}
let messageType = userInfo["message-type"]
as? String ?? "text"
NavigationRouter.shared.navigate(
to: .chat(chatId: chatId,
messageType: messageType))
completionHandler()
}
L’estensione di servizio riceve il payload prima che la notifica venga visualizzata e può modificarlo. La convalida del payload è il primo passo in didReceive: verifica i campi personalizzati obbligatori, convalida l’URL dell’allegato e controlla i tipi di dati. Se il payload non è valido, chiama immediatamente il completion handler con il contenuto originale per evitare di sprecare tempo in elaborazioni inutili.
Per eseguire il debug delle notifiche push in produzione, utilizza la registrazione strutturata dei payload. OSLog consente di registrare il payload con la categoria “notifications” a livello di debug. Sul lato server, monitora le risposte APNS: una risposta riuscita contiene apns-id per corrispondere al payload inviato, mentre un errore 400 indica JSON non valido o superamento della dimensione.
Domande Frequenti
La dimensione massima del payload è di 4096 byte per le notifiche push normali e di 5120 byte per le VoIP push (PushKit). Il superamento di questo limite fa sì che APNS restituisca un errore 400 Bad Request. La dimensione viene calcolata in byte, non in caratteri — considera la codifica UTF-8.
Utilizza le chiavi loc-key, title-loc-key, loc-args e title-loc-args all’interno di alert. L’app sostituisce la traduzione dal suo Localizable.strings in base alla lingua del dispositivo. Ciò consente di inviare un unico payload a tutti i dispositivi indipendentemente dalla lingua.
content-available attiva l’app in background per l’elaborazione dei dati (silent push) senza mostrare una notifica. mutable-content attiva l’estensione di servizio per modificare il contenuto prima della visualizzazione. Entrambe le chiavi possono essere utilizzate insieme per l’elaborazione in background e la successiva modifica della notifica.
Utilizza APNS Sandbox per i test e verifica la risposta HTTP del server Apple: 200 OK significa consegna riuscita. Per la convalida della struttura, utilizza schemi JSON nella pipeline CI/CD. In Xcode, invia notifiche di test tramite il simulatore con xcrun simctl push.
apns-id è un identificatore univoco di notifica push nel sistema APNS, restituito nella risposta in caso di consegna riuscita. Viene utilizzato per tracciare la consegna tramite l’API Logs e per il debug. Il server dovrebbe memorizzare apns-id per ogni notifica inviata.
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