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 уведомление чрез HTTP/2 API на 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 (пробива фокуса, изисква special entitlement) и critical (медицински/спешни ситуации). Ключът relevance-score (0–1) помага на системата Focus да класира уведомленията в рамките на една категория.
Ключът thread-id обединява уведомленията в групи в Notification Center. Всички уведомления с еднакъв 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 и Rich Notification с медиен прикачен файл.
Основен пейлоуд с текст и звук — минимална конфигурация за показване на уведомление на потребителя. 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 pipeline. В Xcode изпращайте тестови уведомления чрез симулатора с командата xcrun simctl push.
apns-id — уникален идентификатор на push уведомлението в системата APNS, който се връща в отговор на успешно изпращане. Използва се за проследяване на доставка чрез Logs API и за отстраняване на грешки. Сървърът трябва да запазва apns-id за всяко изпратено уведомление.
Резюме
Ще разработим мобилно приложение под ключ
IT Sectr създава iOS и Android приложения за стартъпи и бизнеси от 2017 г. Ще ви консултираме и ще предложим най-доброто решение.
Прочетете също