Notification Payload ist eine JSON-Struktur, die der Server über APNS an ein iOS-Gerät sendet und den Inhalt einer Push-Benachrichtigung sowie das Verhalten beim Empfang definiert. Der Payload enthält obligatorische und optionale Schlüssel, die Text, Ton, Badge, Medienanhänge und Hintergrundverarbeitung steuern. Laut Apple Developer Documentation, 2026 beträgt die maximale Payload-Größe 4096 Byte für normale Benachrichtigungen und 5120 Byte für VoIP-Push, was strenge Grenzen für die Menge der übertragenen Daten auferlegt.
Wichtige Punkte
Notification Payload ist ein JSON-Objekt, das der Server an APNS (Apple Push Notification Service) sendet, um es an ein iOS-Gerät zuzustellen. Der Payload enthält alle Daten, die das System zur Anzeige der Benachrichtigung benötigt: Titel, Text, Ton, Badge und Metadaten für die Hintergrundverarbeitung. Die Payload-Struktur wird von Apple streng reguliert und enthält obligatorische Schlüssel für die korrekte Verarbeitung durch das System.
Wenn der Server eine Push-Benachrichtigung über die APNS-HTTP/2-API sendet, enthält die Anfrage Autorisierungs-Header und einen JSON-Body — den Payload. APNS validiert den Payload: Wenn das JSON ungültig ist oder die Größenbeschränkung überschreitet, gibt der Apple-Server einen 400 Bad Request-Fehler zurück. Nach der Validierung stellt APNS den Payload an das Gerät zu, wo iOS ihn analysiert und bestimmt, wie die Benachrichtigung zu behandeln ist — ein Banner anzeigen, eine Hintergrundaufgabe ausführen oder einen Ton abspielen.
Das APNS-Payload-Format hat sich von einem einfachen Text-Payload in iOS 2 zu einer mehrkomponentigen JSON-Struktur in modernen Versionen entwickelt. iOS 10 führte Unterstützung für Medienanhänge über mutable-content ein, iOS 12 fügte die Gruppierung von Benachrichtigungen über thread-id hinzu, und iOS 15 führte supports-live-activities für Live Activities ein. Heute kann ein Payload je nach gewünschtem Benachrichtigungsverhalten bis zu 15 verschiedene Schlüssel enthalten.
Das Root-Objekt des Payloads enthält ein aps-Wörterbuch und optionale benutzerdefinierte Felder auf der obersten Ebene. Das aps-Wörterbuch ist das einzige obligatorische Element, aber darin können je nach Benachrichtigungstyp verschiedene Schlüsselkombinationen vorkommen: alert, badge, sound, content-available, mutable-content, interruption-level und andere.
| aps-Schlüssel | Typ | Zweck |
|---|---|---|
| alert | String oder Dictionary | Benachrichtigungstext oder Objekt mit title, subtitle, body und Lokalisierung |
| badge | Number | Zahl auf dem App-Symbol; 0 entfernt das Badge |
| sound | String | Name der Audiodatei oder default für den Systemton |
| content-available | Number (1) | Hintergrundaktivierungs-Flag; 1 = Silent Push |
| mutable-content | Number (1) | Flag zur Aktivierung der Service Extension zur Inhaltsänderung |
| category | String | Kategoriekennung für Schaltflächen und Content Extension |
| thread-id | String | Gruppenkennung zur Gruppierung von Benachrichtigungen |
| interruption-level | String | Unterbrechungsstufe: passive, active, time-sensitive, critical |
| relevance-score | Number (0–1) | Benachrichtigungspriorität für das intelligente Rankingsystem |
Der alert-Schlüssel kann ein einfacher String (der zum Benachrichtigungstext wird) oder ein Dictionary mit den Feldern title, subtitle und body sein. Das Dictionary-Format ermöglicht es, Titel und Untertitel getrennt vom Haupttext festzulegen. Für lokalisierte Benachrichtigungen werden die Schlüssel title-loc-key, title-loc-args, loc-key und loc-args verwendet, die auf Localizable.strings der App verweisen. Dies ermöglicht das Senden eines Payloads ohne sprachspezifischen Text — die App setzt die Übersetzung ein.
Ab iOS 15 hat Apple den Focus-Mode-Mechanismus eingeführt, der vom Entwickler verlangt, die Unterbrechungsstufe der Benachrichtigung anzugeben. interruption-level akzeptiert die Werte: passive (kein Ton, kein Bildschirmaufwachen), active (Standardverhalten), time-sensitive (durchbricht den Fokus, benötigt spezielle Berechtigung) und critical (medizinische/Notfallsituationen). Der relevance-score (0–1) hilft dem Focus-System, Benachrichtigungen innerhalb einer Kategorie zu ordnen.
Der thread-id-Schlüssel gruppiert Benachrichtigungen im Benachrichtigungscenter. Alle Benachrichtigungen mit derselben thread-id werden als eine einzelne Gruppe angezeigt, die der Benutzer erweitern kann. Dies ist besonders nützlich für Messenger, bei denen Nachrichten von einem Kontakt zusammengefasst werden, oder für Apps, die viele Benachrichtigungen desselben Typs senden.
Benutzerdefinierte Felder sind beliebige Schlüssel außerhalb des aps-Wörterbuchs, die der Entwickler hinzufügt, um zusätzliche Daten an das Gerät zu übertragen. Der Server fügt sie in das Root-JSON-Objekt des Payloads ein, und die App ruft sie über userInfo in UNNotificationContent ab. Benutzerdefinierte Felder dürfen keine Schlüsselnamen aus aps duplizieren, um Konflikte bei der Analyse zu vermeiden.
Die Haupteinschränkung ist, dass die Gesamtgröße des Payloads 4096 Byte nicht überschreiten darf. Benutzerdefinierte Felder konkurrieren mit den obligatorischen aps-Schlüsseln um dieses Limit, daher ist es wichtig, die Größe der übertragenen Daten zu minimieren. Verwenden Sie kurze Schlüsselnamen (z.B. „uid“ statt „user-id“), vermeiden Sie große JSON-Strukturen und übertragen Sie nur Kennungen statt vollständiger Datenobjekte.
Benutzerdefinierte Felder kommen vom Server und sollten nicht ohne Überprüfung vertraut werden. Validieren Sie immer die Typen und Werte benutzerdefinierter Felder beim Parsen: überprüfen Sie die Existenz des Schlüssels über optionales Binding, konvertieren Sie mit as? String/Int/Dictionary in den erwarteten Typ und behandeln Sie den Fall fehlender Werte. Verwenden Sie niemals force unwrap (!) für Daten aus dem Payload — der Server könnte ungültige Daten senden, was zum Absturz der App führen würde.
{
"aps": {
"alert": {
"title": "Neue Nachricht",
"body": "Hallo! Wie geht es dir?"
},
"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"
}
Verwenden Sie einen einheitlichen Namensstil für benutzerdefinierte Felder in allen Payloads des Projekts. kebab-case (message-type) oder camelCase (messageType) — beide Ansätze sind akzeptabel, aber die Konsistenz innerhalb des Projekts ist wichtig. Vermeiden Sie lange Namen: „uid“ statt „user-identifier“, „img“ statt „profile-image-url“. Jedes Zeichen in einem Schlüsselnamen verbraucht ein Byte des 4096-Limits.
Verschiedene Szenarien von Push-Benachrichtigungen erfordern unterschiedliche Schlüsselkombinationen im Payload. Betrachten wir mehrere typische Beispiele: eine einfache Textbenachrichtigung, eine lokalisierte Benachrichtigung, einen Silent Push und eine Rich Notification mit Medienanhang.
Ein einfacher Payload mit Text und Ton — die Mindestkonfiguration zur Anzeige einer Benachrichtigung für den Benutzer. Alert als String liefert eine kurze Nachricht, sound default spielt den Standardsystemton ab. Badge ist optional und setzt den Zähler auf dem App-Symbol. category und thread-id werden für Gruppierung und Interaktivität hinzugefügt.
{
"aps": {
"alert": "Erinnerung: Besprechung in 15 Minuten",
"badge": 3,
"sound": "default"
}
}
Um Benachrichtigungen an Geräte mit unterschiedlichen Sprachen zu senden, verwenden Sie Lokalisierungsschlüssel anstelle von fest codiertem Text. title-loc-key verweist auf einen Schlüssel in den Localizable.strings der App, und title-loc-args liefert Argumente. Dies ermöglicht das Senden eines einzigen Payloads an alle Geräte, und die App zeigt den Text in der entsprechenden Sprache an.
{
"aps": {
"alert": {
"title-loc-key": "NEW_MESSAGE_TITLE",
"title-loc-args": ["Anna"],
"loc-key": "NEW_MESSAGE_BODY",
"loc-args": ["Hallo!"]
},
"sound": "message.caf"
}
}
Für Hintergrundsynchronisation ohne Anzeige einer Benachrichtigung verwenden Sie content-available: 1 ohne alert. Benutzerdefinierte Felder geben den Vorgangstyp und die zu verarbeitenden Daten an. Das System aktiviert die App im Hintergrund, ruft didReceiveRemoteNotification mit fetchCompletionHandler auf, und die App führt die Synchronisation durch.
{
"aps": {
"content-available": 1
},
"sync-type": "invalidate-cache",
"timestamp": "2026-07-03T12:00:00Z"
}
Um einen Medienanhang anzuzeigen, wird mutable-content: 1 benötigt, um die Service Extension zu aktivieren, zusammen mit einer Bild-URL in einem benutzerdefinierten Feld. mutable-content: 1 signalisiert dem System, UNNotificationServiceExtension zu starten, das das Bild von der URL herunterlädt und als UNNotificationAttachment hinzufügt. Der category-Schlüssel gibt eine registrierte Kategorie zur Anzeige von Aktionsschaltflächen an.
{
"aps": {
"alert": {
"title": "Neues Produkt",
"body": "Schauen Sie sich die neue Kollektion an"
},
"category": "product",
"mutable-content": 1
},
"media-url": "https://cdn.example.com/product.jpg"
}
UNNotificationContent.userInfo enthält das vollständige Wörterbuch des empfangenen Payloads nach der Systemverarbeitung. Die App greift auf den Payload im UNUserNotificationCenter-Delegierten beim Empfang einer Benachrichtigung (im Vordergrund), beim Tippen auf eine Benachrichtigung sowie in der Service Extension und Content Extension zu. Korrektes Parsing ist für das Extrahieren benutzerdefinierter Daten und die Bestimmung weiterer Aktionen unerlässlich.
Wenn der Benutzer auf eine Benachrichtigung tippt, ruft das System die didReceive-Methode im UNUserNotificationCenterDelegate auf. response.notification.request.content.userInfo enthält den vollständigen Payload. Der Entwickler extrahiert benutzerdefinierte Felder, bestimmt den Aktionstyp (z.B. Chat öffnen, zu einem Produkt navigieren) und löst die entsprechende Navigation in der App aus.
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()
}
Die Service Extension erhält den Payload vor der Anzeige der Benachrichtigung und kann ihn ändern. Die Payload-Validierung ist der erste Schritt in didReceive: überprüfen Sie obligatorische benutzerdefinierte Felder, validieren Sie die Anhangs-URL und überprüfen Sie die Datentypen. Wenn der Payload ungültig ist, rufen Sie sofort den completion handler mit dem ursprünglichen Inhalt auf, um keine Zeit mit unnötiger Verarbeitung zu verschwenden.
Für das Debuggen von Push-Benachrichtigungen in der Produktion verwenden Sie strukturierte Payload-Protokollierung. OSLog ermöglicht die Protokollierung des Payloads mit der Kategorie „notifications“ auf Debug-Ebene. Überwachen Sie auf Serverseite die APNS-Antworten: Eine erfolgreiche Antwort enthält eine apns-id zur Zuordnung zum gesendeten Payload, während ein 400-Fehler auf ungültiges JSON oder Größenüberschreitung hinweist.
Häufig gestellte Fragen
Die maximale Payload-Größe beträgt 4096 Byte für reguläre Push-Benachrichtigungen und 5120 Byte für VoIP-Push (PushKit). Bei Überschreitung dieses Limits gibt APNS einen 400 Bad Request-Fehler zurück. Die Größe wird in Byte und nicht in Zeichen gezählt — berücksichtigen Sie die UTF-8-Kodierung.
Verwenden Sie die Schlüssel loc-key, title-loc-key, loc-args und title-loc-args innerhalb von alert. Die App setzt die Übersetzung aus ihren Localizable.strings basierend auf der Gerätesprache ein. Dies ermöglicht das Senden eines einzigen Payloads an alle Geräte unabhängig von deren Sprache.
content-available aktiviert die App im Hintergrund zur Datenverarbeitung (Silent Push), ohne eine Benachrichtigung anzuzeigen. mutable-content aktiviert die Service Extension zur Änderung des Inhalts vor der Anzeige. Beide Schlüssel können zusammen für Hintergrundverarbeitung und anschließende Änderung der Benachrichtigung verwendet werden.
Verwenden Sie APNS Sandbox zum Testen und überprüfen Sie die HTTP-Antwort des Apple-Servers: 200 OK bedeutet erfolgreiche Zustellung. Zur Strukturvalidierung verwenden Sie JSON-Schemata in Ihrer CI/CD-Pipeline. In Xcode senden Sie Testbenachrichtigungen über den Simulator mit xcrun simctl push.
apns-id ist eine eindeutige Push-Benachrichtigungskennung im APNS-System, die bei erfolgreicher Zustellung in der Antwort zurückgegeben wird. Sie wird zur Verfolgung der Zustellung über die Logs-API und zum Debuggen verwendet. Der Server sollte apns-id für jede gesendete Benachrichtigung speichern.
Zusammenfassung
Wir entwickeln eine mobile Applikation schlüsselfertig
IT Sectr entwickelt seit 2017 iOS- und Android-Apps für Startups und Unternehmen. Wir beraten Sie und schlagen die beste Lösung vor.
Lesen Sie auch