Notification Payload — це JSON-структура, яку сервер надсилає через APNS на пристрій iOS, визначаючи вміст push-повідомлення та поведінку при його отриманні. Пейлоуд включає обов’язкові та опціональні ключі, що керують текстом, звуком, badge, медіа-вкладеннями та фоновим обробленням. Згідно з Apple Developer Documentation, 2026, максимальний розмір пейлоуду становить 4096 байтів для звичайних сповіщень та 5120 байтів для VoIP push, що накладає суворі обмеження на обсяг передаваних даних.
Головне
Notification Payload — це JSON-об’єкт, який сервер надсилає в APNS (Apple Push Notification Service) для доставки на пристрій iOS. Пейлоуд містить всі дані, необхідні системі для відображення сповіщення: заголовок, текст, звук, badge та метадані для фонового оброблення. Структура пейлоуду суворо регламентована Apple і включає обов’язкові ключі для коректного оброблення системою.
Коли сервер надсилає push-сповіщення через API HTTP/2 APNS, запит містить заголовки авторизації та JSON-тіло — пейлоуд. APNS перевіряє пейлоуд: якщо JSON некоректний або перевищує ліміт розміру, сервер Apple повертає помилку 400 Bad Request. Після перевірки APNS доставляє пейлоуд на пристрій, де iOS аналізує його та визначає, як обробляти сповіщення — показати банер, запустити фонове завдання або відтворити звук.
Формат пейлоуду APNS еволюціонував від простого текстового пейлоуду в iOS 2 до багатокомпонентної JSON-структури в сучасних версіях. iOS 10 приніс підтримку медіа-вкладень через mutable-content, iOS 12 додав групування сповіщень через thread-id, а iOS 15 ввів supports-live-activities для Live Activities. Сьогодні пейлоуд може містити до 15 різних ключів залежно від бажаної поведінки сповіщення.
Кореневий об’єкт пейлоуду містить словник aps та опціональні кастомні поля на верхньому рівні. Словник aps — єдиний обов’язковий елемент, але всередині нього можуть присутні різні комбінації ключів залежно від типу сповіщення: alert, badge, sound, content-available, mutable-content, interruption-level та інші.
| Ключ aps | Тип | Призначення |
|---|---|---|
| alert | String або Dictionary | Текст сповіщення або об’єкт з title, subtitle, body та локалізацією |
| badge | Number | Число на значку додатка; 0 видаляє badge |
| sound | String | Ім’я звукового файлу або default для системного звуку |
| content-available | Number (1) | Прапорець фонової активації; 1 = silent push |
| mutable-content | Number (1) | Прапорець активації Service Extension для модифікації вмісту |
| category | String | Ідентифікатор категорії для кнопок та Content Extension |
| thread-id | String | Ідентифікатор групи для групування сповіщень |
| interruption-level | String | Рівень переривання: passive, active, time-sensitive, critical |
| relevance-score | Number (0–1) | Пріоритет сповіщення для системи інтелектуального ранжування |
Ключ alert може бути простою рядком (яка стає тілом сповіщення) або словником з полями title, subtitle та body. Словниковий формат дозволяє задавати заголовок та підзаголовок окремо від основного тексту. Для локалізованих сповіщень використовуються ключі title-loc-key, title-loc-args, loc-key та loc-args, які посилаються на Localizable.strings додатка. Це дозволяє надсилати пейлоуд без тексту конкретною мовою — додаток підставляє переклад.
Починаючи з iOS 15, Apple представила механізм Focus Mode, який вимагає від розробника зазначати рівень переривання сповіщення. interruption-level приймає значення: passive (без звуку, без пробудження екрану), active (стандартна поведінка), time-sensitive (пробиває Фокус, потребує спеціального дозволу) та critical (медичні/надзвичайні ситуації). Ключ relevance-score (0–1) допомагає системі Focus ранжувати сповіщення в межах однієї категорії.
Ключ thread-id об’єднує сповіщення в Центрі сповіщень. Усі сповіщення з однаковим thread-id відображаються як одна група, яку користувач може розгорнути. Це особливо корисно для месенджерів, де повідомлення від одного контакту групуються разом, або для додатків, які надсилають багато сповіщень одного типу.
Кастомні поля — це будь-які ключі поза межами словника aps, які розробник додає для передачі додаткових даних на пристрій. Сервер включає їх у кореневий JSON-об’єкт пейлоуду, а додаток отримує їх через userInfo в UNNotificationContent. Кастомні поля не повинні дублювати імена ключів aps, щоб уникнути конфліктів при парсингу.
Головне обмеження — загальний розмір пейлоуду не повинен перевищувати 4096 байтів. Кастомні поля конкурують за цей ліміт з обов’язковими ключами aps, тому важливо мінімізувати розмір передаваних даних. Використовуйте короткі імена ключів (наприклад, «uid» замість «user-id»), уникайте великих JSON-структур та передавайте лише ідентифікатори замість повних об’єктів даних.
Кастомні поля надходять від сервера і не слід довіряти їм без перевірки. Завжди перевіряйте типи та значення кастомних полів при парсингу: перевіряйте наявність ключа через optional binding, конвертуйте в очікуваний тип за допомогою as? String/Int/Dictionary та обробляйте випадок відсутності значення. Ніколи не використовуйте force unwrap (!) для даних з пейлоуду — сервер може надіслати некоректні дані, і додаток завершиться крешем.
{
"aps": {
"alert": {
"title": "Нове повідомлення",
"body": "Привіт! Як справи?"
},
"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"
}
Використовуйте єдиний стиль найменування кастомних полів у всіх пейлоудах проєкту. kebab-case (message-type) або camelCase (messageType) — обидва підходи прийнятні, але важлива постійність у межах проєкту. Уникайте довгих імен: «uid» замість «user-identifier», «img» замість «profile-image-url». Кожен символ в імені ключа споживає один байт ліміту 4096.
Різні сценарії push-сповіщень вимагають різних комбінацій ключів у пейлоуді. Розглянемо кілька типових прикладів: просте текстове сповіщення, локалізоване сповіщення, Silent Push та Багате сповіщення з медіа-вкладенням.
Базовий пейлоуд з текстом та звуком — мінімальна конфігурація для відображення сповіщення користувачеві. Alert як рядок надає коротке повідомлення, sound default відтворює стандартний системний звук. Badge необов’язковий і встановлює лічильник на значку додатка. category та thread-id додаються для групування та інтерактивності.
{
"aps": {
"alert": "Нагадування: зустріч через 15 хвилин",
"badge": 3,
"sound": "default"
}
}
Щоб надсилати сповіщення на пристрої з різними мовами, використовуйте ключі локалізації замість жорстко заданого тексту. title-loc-key посилається на ключ у Localizable.strings додатка, а title-loc-args надає аргументи. Це дозволяє надсилати один пейлоуд на всі пристрої, і додаток відображає текст відповідною мовою.
{
"aps": {
"alert": {
"title-loc-key": "NEW_MESSAGE_TITLE",
"title-loc-args": ["Анна"],
"loc-key": "NEW_MESSAGE_BODY",
"loc-args": ["Привіт!"]
},
"sound": "message.caf"
}
}
Для фонової синхронізації без показу сповіщення використовуйте content-available: 1 без alert. Кастомні поля вказують тип операції та дані для обробки. Система активує додаток у фоні, викликає didReceiveRemoteNotification з fetchCompletionHandler, і додаток виконує синхронізацію.
{
"aps": {
"content-available": 1
},
"sync-type": "invalidate-cache",
"timestamp": "2026-07-03T12:00:00Z"
}
Для відображення медіа-вкладення потрібен mutable-content: 1 для активації Service Extension та URL зображення у кастомному полі. mutable-content: 1 сигналізує системі запустити UNNotificationServiceExtension, який завантажує зображення з URL та додає його як UNNotificationAttachment. category вказує на зареєстровану категорію для відображення кнопок дій.
{
"aps": {
"alert": {
"title": "Новий товар",
"body": "Перегляньте нову колекцію"
},
"category": "product",
"mutable-content": 1
},
"media-url": "https://cdn.example.com/product.jpg"
}
UNNotificationContent.userInfo містить повний словник отриманого пейлоуду після обробки системою. Додаток отримує доступ до пейлоуду в делегаті UNUserNotificationCenter при отриманні сповіщення (на передньому плані), при натисканні на сповіщення, а також у Service Extension та Content Extension. Коректний парсинг обов’язковий для вилучення кастомних даних та визначення подальших дій.
Коли користувач натискає на сповіщення, система викликає метод didReceive response в UNUserNotificationCenterDelegate. response.notification.request.content.userInfo містить повний пейлоуд. Розробник вилучає кастомні поля, визначає тип дії (наприклад, відкрити чат, перейти на товар) та активує відповідну навігацію в додатку.
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()
}
Service Extension отримує пейлоуд до показу сповіщення та може модифікувати його. Перевірка пейлоуду — перший крок у didReceive: перевірте наявність обов’язкових кастомних полів, перевірте URL вкладення та типи даних. Якщо пейлоуд недійсний, негайно викличіть completion handler з оригінальним вмістом, щоб не витрачати час на непотрібне оброблення.
Для налагодження push-сповіщень на продакшні використовуйте структуроване логування пейлоудів. OSLog дозволяє логувати пейлоуд з категорією «notifications» на рівні debug. На серверному боці відстежуйте відповіді APNS: успішна відповідь містить apns-id для зіставлення з надісланим пейлоудом, а помилка 400 вказує на некоректний JSON або перевищення розміру.
Часто задавані питання
Максимальний розмір пейлоуду — 4096 байтів для звичайних push-сповіщень та 5120 байтів для VoIP push (PushKit). При перевищенні APNS повертає помилку 400 Bad Request. Розмір рахується в байтах, а не в символах — враховуйте UTF-8 кодування.
Використовуйте ключі loc-key, title-loc-key, loc-args та title-loc-args всередині alert. Додаток підставляє переклад із свого Localizable.strings на основі мови пристрою. Це дозволяє надсилати один пейлоуд на всі пристрої незалежно від їхньої мови.
content-available активує додаток у фоні для обробки даних (silent push) без показу сповіщення. mutable-content активує Service Extension для модифікації вмісту перед показом. Обидва ключі можна використовувати разом для фонового оброблення та подальшої модифікації сповіщення.
Використовуйте APNS Sandbox для тестування та перевіряйте HTTP-відповідь сервера Apple: 200 OK означає успішну доставку. Для перевірки структури використовуйте JSON-схеми у своєму CI/CD конвеєрі. У Xcode надсилайте тестові сповіщення через симулятор командою xcrun simctl push.
apns-id — унікальний ідентифікатор push-сповіщення в системі APNS, що повертається у відповіді при успішній доставці. Використовується для відстеження доставки через Logs API та для налагодження. Сервер повинен зберігати apns-id для кожного надісланого сповіщення.
Підсумки
Ми розробимо мобільний застосунок під ключ
IT Sectr створює застосунки для iOS та Android для стартапів і бізнесу з 2017 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.
Читайте також