APNS (Apple Push Notification Service) — това е инфраструктурна услуга на Apple за доставка на push известия до устройствата от екосистемата: iPhone, iPad, Mac, Apple Watch и Apple TV. Услугата осигурява надеждно предаване на съобщения чрез постоянна TLS връзка между устройството и сървърите на Apple. Според Apple Developer Documentation, APNS използва HTTP/2 протокол за двупосочна комуникация със сървърите на приложенията.
Най-важното
Apple Push Notification Service (APNS) — това е собствена услуга на Apple за маршрутизиране на push известия от сървъра на приложението до устройствата на потребителите. За разлика от FCM, APNS не поддържа Android или други платформи — той е напълно обвързан с екосистемата на Apple.
Услугата работи чрез постоянна TLS връзка, която всяко устройство на Apple установява със сървърите на APNS при включване. Тази връзка се поддържа във фонов режим и се използва за доставка на известия с минимално закъснение.
APNS поема цялата инфраструктура за доставка: криптиране, удостоверяване, приоритизиране и повторно изпращане в случай на недостъпност на устройството. Разработчикът трябва само да предостави правилно оформен payload и валиден push token.
Първоначално APNS работеше чрез бинарен протокол на порт 2195–2196. От 2015 г. Apple прехвърли услугата на съвременния HTTP/2 протокол, който поддържа мултиплексиране, компресия на заглавките и push известия от сървъра. HTTP/2 стана задължителен от юни 2020 г.
Процесът на доставка на push известие чрез APNS се състои от пет етапа: регистрация на устройството, получаване на push token, изпращане на заявката от сървъра, маршрутизиране от APNS и доставка до устройството.
Ако устройството е недостъпно (изключено или без мрежа), APNS съхранява последното съобщение за всяко приложение и го доставя при възстановяване на връзката. Максималният срок на съхранение е 4 седмици, след което съобщението се изтрива.
Apple поддържа два начина за удостоверяване на сървъра на приложението при изпращане на push известия. Всеки начин има своите особености по отношение на срока на валидност, управлението и удобството на използване.
| Параметър | Token-based (p8) | Certificate-based (.p12) |
|---|---|---|
| Срок на валидност | Безсрочен (ключът не изтича) | Ограничен от срока на сертификата (обикновено 1 година) |
| Ротация | Не е необходима, ако ключът не е компрометиран | Задължителна ежегодна смяна |
| Мултиприложност | Един ключ за всички приложения на акаунта | Отделен сертификат за всяко приложение |
| Среда | Един ключ за Sandbox и Production | Различни сертификати за Sandbox и Production |
Token-based удостоверяването е препоръчаният от Apple начин от 2019 г. Създавате един p8 ключ в Apple Developer Console, качвате го на сървъра и подписвате с него всяка APNS заявка. Ключът не изтича и работи за всички приложения на вашия акаунт.
За нови проекти Token-based удостоверяването е категорично за предпочитане: един p8 ключ за целия акаунт, безсрочен, без обвързване със среда. Certificate-based (.p12) все още се използва в legacy проекти, но изисква ежегодна смяна и отделни сертификати за Sandbox и Production. Вземете предвид срока на изтичане на сертификата при планиране на CI/CD.
APNS поддържа три типа push известия, които се различават по поведението на устройството и изискванията към атрибутите на заявката. Изборът на тип зависи от UX сценария и спешността на съобщението.
За Background известия е необходимо да посочите ключа content-available: 1 и да зададете приоритет 5 (енергийно ефективна доставка). Системата може да ограничи броя на фоновите известия, ако приложението не ги обработва своевременно.
APNS поддържа две стойности на приоритета: 10 (незабавна доставка) и 5 (енергийно ефективна). За alert известия използвайте 10 — потребителят трябва да ги получи веднага. За background известия използвайте 5 — системата може да забави доставката, за да спести батерия. Некоректен приоритет за background може да доведе до отхвърляне на известието от APNS.
APNS приема payload във формат JSON с максимален размер 4 КБ за обикновени известия и 5 КБ за VOIP. Payload съдържа задължителния речник aps с настройки за показване и опционални персонализирани полета.
{
"aps": {
"alert": {
"title": "Ново съобщение",
"body": "Имате 3 непрочетени чата"
},
"badge": 3,
"sound": "default",
"category": "message_category",
"thread-id": "chat_room_42"
},
"customData": {
"chatId": "42"
}
}
Ключът thread-id обединява известията в групи в Центъра за известия на iOS. Ключът category свързва известието с UNNotificationCategory за показване на бутони за действия. Без тези ключове всички известия се показват поотделно.
Освен задължителния речник aps, APNS пейлоудът може да съдържа всякакви персонализирани полета на най-високо ниво. Тези полета са достъпни за приложението чрез речника userInfo при обработката на известието. Персонализираните данни са удобни за предаване на идентификатори на обекти, екрани или връзки. Максималният размер на пейлоуда е 4 КБ, затова избягвайте предаването на големи обеми данни чрез push; зареждайте ги чрез API след отваряне на известието.
За изпращане на push известие на сървъра е необходимо да изпълните POST заявка към APNS endpoint с коректни заглавки за удостоверяване. По-долу е даден пример на Node.js с използване на Token-based удостоверяване.
const http2 = require("http2")
const fs = require("fs")
const jwt = require("jsonwebtoken")
const token = jwt.sign(
{ iss: "TEAM_ID", iat: Math.floor(Date.now() / 1000) },
fs.readFileSync("AuthKey.p8"),
{ algorithm: "ES256", keyid: "KEY_ID" }
)
const payload = JSON.stringify({
aps: { alert: { title: "Здравей!", body: "Тестово push" } }
})
const client = http2.connect(
"https://api.push.apple.com"
)
const req = client.request({
":method": "POST",
":path": "/3/device/DEVICE_PUSH_TOKEN",
"authorization": "bearer " + token,
"apns-push-type": "alert",
"apns-topic": "com.example.app",
"apns-priority": "10"
})
req.end(payload)
req.on("response", (headers) => {
if (headers[":status"] === 200) {
console.log("Push е изпратено успешно")
}
})
След изпращането APNS връща HTTP статус 200 при успешна доставка или код на грешка с описание в тялото на отговора. Важно е да обработвате грешката token-unregistered (410) — такъв токен трябва да се изтрие от сървъра, тъй като приложението е било премахнато от устройството.
APNS връща HTTP статуси за всяка заявка за изпращане. Успешното изпращане е статус 200. Грешките изискват различни стратегии за обработка. BadDeviceToken (400) или Unregistered (410) — токенът на устройството е остарял и трябва да бъде изтрит от сървъра. PayloadTooLarge (413) — надвишен е лимитът от 4 КБ, намалете пейлоуда.
Грешката TooManyRequests (429) — надвишен е лимитът на заявките. APNS задава квота за броя изпращания в секунда. При получаване на 429 е необходимо да внедрите експоненциално забавяне (exponential backoff) и да повторите изпращането. Препоръчително е да не надвишавате 100 заявки в секунда на една HTTP/2 връзка.
Грешките от страна на APNS са 500 и 503 (Internal Server Error / Service Unavailable). Това са временни повреди в инфраструктурата на Apple. В такива случаи повтаряйте изпращането със закъснение от 1–5 секунди, не повече от 3 опита. Постоянните грешки 5xx при напълно работещ сървър са рядко явление, обикновено свързано с проблеми на TLS връзката.
За Production среда задължително реализирайте регистриране на всички грешки на APNS с посочване на токена, кода на грешката и времето. Това ще помогне бързо да откриете проблеми със сертификати, квоти или конкретни токени на устройства. Редовно проверявайте срока на валидност на сертификатите, ако използвате Certificate-based удостоверяване.
Често задавани въпроси
APNS работи чрез TCP 443 (HTTPS) за HTTP/2 API. По-рано се използваха портове 2195 и 2196 за бинарния протокол. От юни 2020 г. Apple изисква използването единствено на HTTP/2 на порт 443. Уверете се, че сървърът има достъп до api.push.apple.com.
Sandbox е тестова среда на APNS за отстраняване на грешки в push известията. Production е работна среда за реални потребители. При Token-based удостоверяване един ключ работи за двете среди — endpoint се различава: api.sandbox.push.apple.com или api.push.apple.com.
Push token може да се промени при: възстановяване на приложението от бекъп, преинсталиране на приложението, обновяване на ОС, нулиране на мрежовите настройки. Token не се променя при обичайни обновления на приложението през App Store. Сървърът трябва да обработва грешката BadDeviceToken (400) като сигнал за изтриване на токена.
4 КБ (4096 байта) за обикновени alert/background известия. За VOIP известия чрез PushKit — 5 КБ (5120 байта). Превишаването на размера връща грешка PayloadTooLarge (413). Препоръчително е да пазите payload минимален и да зареждате допълнителни данни през сървъра.
APNS не може да достави известие на устройство без интернет връзка. Ако устройството е офлайн, APNS съхранява последното съобщение (per app per device) до 28 дни. При възстановяване на връзката съобщението се доставя незабавно. По-старите съобщения не се запазват.
Изводи
Ще разработим мобилно приложение под ключ
IT Sectr създава iOS и Android приложения за стартъпи и бизнеси от 2017 г. Ще ви консултираме и ще предложим най-доброто решение.
Прочетете също