Notification Payload — co to jest, struktura JSON i parsowanie

Autor: IT Sectr Opublikowano: 2026-03-20 Czas czytania: 10 min

Notification Payload — to struktura JSON, którą serwer wysyła przez APNS na urządzenie iOS, określając zawartość powiadomienia push i zachowanie przy jego otrzymaniu. Payload zawiera obowiązkowe i opcjonalne klucze sterujące tekstem, dźwiękiem, badge, załącznikami multimedialnymi i przetwarzaniem w tle. Według Apple Developer Documentation, 2026, maksymalny rozmiar payloadu wynosi 4096 bajtów dla zwykłych powiadomień i 5120 bajtów dla VoIP push, co nakłada ścisłe ograniczenia na ilość przesyłanych danych.

Najważniejsze

  • Struktura aps — obowiązkowy słownik z kluczami alert, badge, sound i content-available, określający wizualne i dźwiękowe zachowanie powiadomienia.
  • Limit rozmiaru — maksymalny rozmiar payloadu 4096 bajtów dla APNS i 5120 bajtów dla VoIP push, wszystko większe jest odrzucane przez serwer Apple.
  • Niestandardowe pola — wszelkie dodatkowe dane są przesyłane na tym samym poziomie co aps i dostępne w userInfo po otrzymaniu powiadomienia.
  • Lokalizacja alert — klucze title-loc-key, loc-key i loc-args pozwalają wyświetlać zlokalizowany tekst bez wysyłania różnych payloadów dla każdego języka.
  • Request-identifier — niestandardowy identyfikator w odpowiedzi APNS do śledzenia statusu dostawy i callbacków od serwera Apple.

Co to jest Notification Payload

Notification Payload (payload powiadomienia) — to obiekt JSON, który serwer wysyła do APNS (Apple Push Notification Service) w celu dostarczenia na urządzenie iOS. Payload zawiera wszystkie dane niezbędne systemowi do wyświetlenia powiadomienia: tytuł, tekst, dźwięk, badge i metadane do przetwarzania w tle. Struktura payloadu jest ściśle regulowana przez Apple i zawiera obowiązkowe klucze do prawidłowego przetwarzania przez system.

Rola payloadu w dostarczaniu push

Gdy serwer wysyła powiadomienie push przez HTTP/2 API APNS, żądanie zawiera nagłówki autoryzacji i ciało JSON — payload. APNS sprawdza poprawność payloadu: jeśli JSON jest nieprawidłowy lub przekracza limit rozmiaru, serwer Apple zwraca błąd 400 Bad Request. Po walidacji APNS dostarcza payload na urządzenie, gdzie system iOS go parsuje i określa, jak przetworzyć powiadomienie — wyświetlić baner, uruchomić zadanie w tle lub odtworzyć dźwięk.

Ewolucja formatu payloadu

Format payloadu APNS ewoluował od prostego tekstowego payloadu w iOS 2 do wieloskładnikowej struktury JSON w nowoczesnych wersjach. iOS 10 przyniosła obsługę załączników multimedialnych przez mutable-content, iOS 12 dodała grupowanie powiadomień przez thread-id, a iOS 15 wprowadziła supports-live-activities dla Live Activities. Obecnie payload może zawierać do 15 różnych kluczy w zależności od wymaganego zachowania powiadomienia.

Struktura APNS-payloadu: obowiązkowe i opcjonalne klucze

Obiekt główny payloadu zawiera słownik aps i opcjonalne niestandardowe pola na najwyższym poziomie. Słownik aps — jedyny obowiązkowy element, ale wewnątrz niego mogą występować różne kombinacje kluczy w zależności od typu powiadomienia: alert, badge, sound, content-available, mutable-content, interruption-level i inne.

Klucz apsTypPrzeznaczenie
alertString lub DictionaryTekst powiadomienia lub obiekt z title, subtitle, body, lokalizacją
badgeNumberLiczba na ikonie aplikacji; 0 usuwa badge
soundStringNazwa pliku dźwiękowego lub default dla systemowego dźwięku
content-availableNumber (1)Flaga aktywacji w tle; 1 = silent push
mutable-contentNumber (1)Flaga aktywacji Service Extension do modyfikacji treści
categoryStringIdentyfikator kategorii dla przycisków i Content Extension
thread-idStringIdentyfikator grupy do grupowania powiadomień
interruption-levelStringPoziom przerwania: passive, active, time-sensitive, critical
relevance-scoreNumber (0–1)Priorytet powiadomienia dla systemu inteligentnego rankingu

Klucz alert: format stringowy i słownikowy

Klucz alert może być prostym ciągiem znaków (który staje się treścią powiadomienia) lub słownikiem z polami title, subtitle, body. Format słownikowy pozwala ustawić tytuł i podtytuł oddzielnie od głównego tekstu. Dla zlokalizowanych powiadomień używane są klucze title-loc-key, title-loc-args, loc-key, loc-args, które odwołują się do Localizable.strings aplikacji. Pozwala to wysyłać payload bez tekstu w konkretnym języku — aplikacja podstawia tłumaczenie.

Zarządzanie przerwaniami: interruption-level i relevance-score

Począwszy od iOS 15 Apple dodała mechanizm Focus Mode, który wymaga od programisty określenia poziomu przerwania powiadomienia. interruption-level przyjmuje wartości: passive (bez dźwięku, bez budzenia ekranu), active (standardowe zachowanie), time-sensitive (przebija focus, wymaga special entitlement) i critical (sytuacje medyczne/awaryjne). Klucz relevance-score (0–1) pomaga systemowi Focus rankingować powiadomienia w ramach jednej kategorii.

Grupowanie powiadomień przez thread-id

Klucz thread-id łączy powiadomienia w grupy w Notification Center. Wszystkie powiadomienia z tym samym thread-id wyświetlają się jako jedna grupa, którą użytkownik może rozwinąć. Jest to szczególnie przydatne dla komunikatorów, gdzie wiadomości od jednego kontaktu są grupowane razem, lub dla aplikacji wysyłających wiele powiadomień tego samego typu.

Niestandardowe pola i przesyłanie danych

Niestandardowe pola — to wszelkie klucze poza słownikiem aps, które programista dodaje do przesyłania dodatkowych danych na urządzenie. Serwer dołącza je do głównego obiektu JSON payloadu, a aplikacja otrzymuje je przez userInfo w UNNotificationContent. Niestandardowe pola nie powinny powielać nazw kluczy z aps, aby uniknąć konfliktów podczas parsowania.

Ograniczenia dotyczące niestandardowych danych

Główne ograniczenie — całkowity rozmiar payloadu nie może przekraczać 4096 bajtów. Niestandardowe pola konkurują o ten limit z obowiązkowymi kluczami aps, dlatego ważne jest minimalizowanie rozmiaru przesyłanych danych. Używaj krótkich nazw kluczy (np. „uid“ zamiast „user-id“), unikaj dużych struktur JSON i przesyłaj tylko identyfikatory, a nie pełne obiekty danych.

Bezpieczeństwo i walidacja niestandardowych pól

Niestandardowe pola pochodzą z serwera i nie należy im ufać bez sprawdzenia. Zawsze waliduj typy i wartości niestandardowych pól podczas parsowania: sprawdzaj obecność klucza przez optional binding, konwertuj na oczekiwany typ za pomocą as? String/Int/Dictionary i obsługuj przypadek braku wartości. Nigdy nie używaj force unwrap (!) dla danych z payloadu — serwer może wysłać nieprawidłowe dane, a aplikacja ulegnie crashowi.

json
{
    "aps": {
        "alert": {
            "title": "Nowa wiadomość",
            "body": "Cześć! Jak się masz?"
        },
        "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"
}

Zalecenia dotyczące nazewnictwa niestandardowych pól

Używaj jednolitego stylu nazewnictwa niestandardowych pól we wszystkich payloadach projektu. kebab-case (message-type) lub camelCase (messageType) — oba podejścia są dopuszczalne, ale ważne jest trzymanie się jednego w ramach projektu. Unikaj długich nazw: „uid“ zamiast „user-identifier“, „img“ zamiast „profile-image-url“. Każdy znak w nazwie klucza to bajt z limitu 4096.

Przykłady payloadów dla różnych typów powiadomień

Różne scenariusze powiadomień push wymagają różnych kombinacji kluczy w payloadzie. Rozważmy kilka typowych przykładów: proste powiadomienie tekstowe, powiadomienie z lokalizacją, Silent Push i Rich Notification z załącznikiem multimedialnym.

Proste powiadomienie tekstowe

Podstawowy payload z tekstem i dźwiękiem — minimalna konfiguracja do wyświetlenia powiadomienia użytkownikowi. Alert jako ciąg znaków daje krótką wiadomość, sound default odtwarza standardowy systemowy dźwięk. Badge jest opcjonalny i ustawia licznik na ikonie. category i thread-id są dodawane do grupowania i interaktywności.

json
{
    "aps": {
        "alert": "Przypomnienie: spotkanie za 15 minut",
        "badge": 3,
        "sound": "default"
    }
}

Powiadomienie z lokalizacją

Do wysyłania na urządzenia z różnymi językami używaj kluczy lokalizacji zamiast sztywno zadanego tekstu. title-loc-key odwołuje się do klucza w Localizable.strings aplikacji, a title-loc-args podstawia argumenty. Pozwala to wysłać jeden payload na wszystkie urządzenia, a aplikacja sama wyświetli tekst w odpowiednim języku.

json
{
    "aps": {
        "alert": {
            "title-loc-key": "NEW_MESSAGE_TITLE",
            "title-loc-args": ["Anna"],
            "loc-key": "NEW_MESSAGE_BODY",
            "loc-args": ["Cześć!"]
        },
        "sound": "message.caf"
    }
}

Silent Push z synchronizacją w tle

Do synchronizacji w tle bez wyświetlania powiadomienia używa się content-available: 1 i braku alert. Niestandardowe pola wskazują typ operacji i dane do przetworzenia. System aktywuje aplikację w tle, wywołuje didReceiveRemoteNotification z fetchCompletionHandler, a aplikacja wykonuje synchronizację.

json
{
    "aps": {
        "content-available": 1
    },
    "sync-type": "invalidate-cache",
    "timestamp": "2026-07-03T12:00:00Z"
}

Rich Notification z obrazem

Do wyświetlania załącznika multimedialnego potrzebny jest mutable-content: 1 do aktywacji Service Extension i URL obrazu w niestandardowym polu. mutable-content: 1 sygnalizuje systemowi uruchomienie UNNotificationServiceExtension, który pobierze obraz pod URL i doda go jako UNNotificationAttachment. category wskazuje na zarejestrowaną kategorię do wyświetlania przycisków akcji.

json
{
    "aps": {
        "alert": {
            "title": "Nowy produkt",
            "body": "Zobacz nową kolekcję"
        },
        "category": "product",
        "mutable-content": 1
    },
    "media-url": "https://cdn.example.com/product.jpg"
}

Przetwarzanie i parsowanie payloadu w aplikacji

UNNotificationContent.userInfo zawiera pełny słownik otrzymanego payloadu po przetworzeniu przez system. Aplikacja uzyskuje dostęp do payloadu w delegacie UNUserNotificationCenter przy otrzymaniu powiadomienia (na pierwszym planie), przy kliknięciu powiadomienia, a także w Service Extension i Content Extension. Prawidłowe parsowanie jest obowiązkowe do wyodrębnienia niestandardowych danych i określenia dalszych działań.

Parsowanie w AppDelegate przy kliknięciu powiadomienia

Gdy użytkownik klika powiadomienie, system wywołuje metodę didReceive response w UNUserNotificationCenterDelegate. W response.notification.request.content.userInfo zawarty jest pełny payload. Programista wyodrębnia niestandardowe pola, określa typ akcji (np. otwarcie czatu, przejście do produktu) i wywołuje odpowiednią nawigację w aplikacji.

swift
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()
}

Walidacja payloadu w Service Extension

Service Extension otrzymuje payload przed wyświetleniem powiadomienia i może go modyfikować. Walidacja payloadu — pierwszy krok w didReceive: sprawdź obecność obowiązkowych niestandardowych pól, poprawność URL dla załączników i typ danych. Jeśli payload jest nieprawidłowy, wywołaj completion handler z oryginalną treścią natychmiast, nie tracąc czasu na bezużyteczne przetwarzanie.

Logowanie i monitorowanie payloadów

Do debugowania powiadomień push na produkcji używaj strukturalnego logowania payloadów. OSLog pozwala logować payload z kategorią „notifications“ i poziomem debug. Po stronie serwera śledź odpowiedzi APNS: pomyślna odpowiedź zawiera apns-id do dopasowania z wysłanym payloadem, a błąd 400 wskazuje na nieprawidłowy JSON lub przekroczenie rozmiaru.

Często zadawane pytania

Jaki jest maksymalny rozmiar payloadu APNS?

Maksymalny rozmiar payloadu — 4096 bajtów dla zwykłych powiadomień push i 5120 bajtów dla VoIP push (PushKit). Przy przekroczeniu APNS zwraca błąd 400 Bad Request. Rozmiar liczony jest w bajtach, nie w znakach — uwzględniaj kodowanie UTF-8.

Jak wysłać zlokalizowane powiadomienie w wielu językach?

Używaj kluczy loc-key, title-loc-key, loc-args i title-loc-args wewnątrz alert. Aplikacja podstawia tłumaczenie ze swojego Localizable.strings na podstawie języka urządzenia. Pozwala to wysłać jeden payload na wszystkie urządzenia niezależnie od ich języka.

Jaka jest różnica między content-available a mutable-content?

content-available aktywuje aplikację w tle do przetwarzania danych (silent push) bez wyświetlania powiadomienia. mutable-content aktywuje Service Extension do modyfikacji treści przed wyświetleniem. Oba klucze mogą być używane razem do przetwarzania w tle i późniejszej modyfikacji powiadomienia.

Jak sprawdzić, że serwer wysłał prawidłowy payload?

Używaj APNS Sandbox do testowania i sprawdzaj odpowiedź HTTP serwera Apple: 200 OK oznacza pomyślne wysłanie. Do walidacji struktury używaj schematów JSON w CI/CD pipeline. W Xcode wysyłaj testowe powiadomienia przez symulator komendą xcrun simctl push.

Co to jest apns-id w odpowiedzi serwera Apple?

apns-id — unikalny identyfikator powiadomienia push w systemie APNS, który jest zwracany w odpowiedzi na pomyślne wysłanie. Używany do śledzenia dostawy przez Logs API i do debugowania. Serwer powinien zapisywać apns-id dla każdego wysłanego powiadomienia.

Podsumowanie

  • Notification Payload — struktura JSON powiadomienia push z obowiązkowym słownikiem aps, określająca tekst, dźwięk, badge i przetwarzanie w tle.
  • Limit rozmiaru — 4096 bajtów dla APNS, 5120 bajtów dla VoIP; przekroczenie zwraca błąd 400 Bad Request od serwera Apple.
  • Słownik aps zawiera klucze alert, badge, sound, content-available, mutable-content, category, thread-id, interruption-level i relevance-score.
  • Niestandardowe pola są przesyłane poza aps i wyodrębniane przez userInfo; zawsze waliduj typy i wartości podczas parsowania.
  • Lokalizacja jest realizowana przez loc-key i title-loc-key, odwołujące się do Localizable.strings aplikacji w celu podstawienia tłumaczenia.
  • interruption-level zarządza zachowaniem powiadomienia w trybie Focus: passive, active, time-sensitive lub critical.
  • Notification Payload — podstawa całego systemu powiadomień push, od której poprawności zależy dostawa, wyświetlenie i przetwarzanie każdego powiadomienia na urządzeniu.

Opracujemy aplikację mobilną pod klucz

IT Sectr tworzy aplikacje na iOS i Androida dla startupów i firm od 2017 roku. Doradzimy Ci i zaproponujemy najlepsze rozwiązanie.

Omów projekt

Przeczytaj również