Device Token е уникален идентификатор, който APNS присвоява на всяко iOS устройство за насочване на push известия. Токенът се генерира от системата при регистрация на приложението за получаване на известия и трябва да бъде предаден на сървъра за изпращане на push именно към това устройство. Според Apple Developer Documentation, 2026, Device Token може да се промени при преинсталиране на приложението, възстановяване на устройството от резервно копие или обновяване на iOS, затова сървърът трябва редовно да обновява токените за осигуряване на доставка.
Основни точки
Device Token (токен на устройството) е уникален идентификатор под формата на hex низ, който APNS (Apple Push Notification Service) генерира за всяко приложение на iOS устройство. Токенът е ключът, по който сървърът изпраща push известия до конкретно устройство. Без коректен Device Token сървърът не може да достави push — APNS отхвърля заявката с грешка 400 BadRequest.
Device Token се създава от iOS системата при първото обръщение на приложението към APNS след инсталация. Процесът на генериране включва криптографска обвързаност с идентификатора на приложението (bundle ID) и уникалния идентификатор на устройството (UID), след което APNS връща 32-байтов токен в hex формат (64 символа). Токенът не е постоянен — системата може да генерира нов при определени условия.
Когато сървърът изпраща push известие, той включва Device Token в HTTP/2 заявката към APNS. APNS проверява валидността на токена: ако токенът принадлежи на друга среда (sandbox вместо production), е изтекъл или е оттеглен, сървърът на Apple връща грешка 410 Gone или 400 BadRequest. Едва след успешно валидиране на токена APNS започва доставка на известието до устройството.
Device Token не трябва да се бърка с IDFA (Identifier for Advertisers), IDFV (Identifier for Vendor) или UID (Unique Device Identifier). IDFA и IDFV се използват за реклама и анализи, UID е хардуерен сериен номер. Device Token съществува изключително за push известия и не разкрива информация за потребителя или устройството извън APNS.
| Идентификатор | Предназначение | Постоянство |
|---|---|---|
| Device Token | Насочване на APNS push известия | Може да се промени |
| IDFA | Реклама и проследяване | Нулира се от потребителя |
| IDFV | Идентификация на доставчик (анализи) | Постоянен за приложения от един разработчик |
| Bundle ID | Уникален идентификатор на приложението | Постоянен |
Процесът на получаване на Device Token се състои от няколко задължителни стъпки, започвайки от искане на разрешение от потребителя и завършвайки с предаване на токена на сървъра. Всяка стъпка е критично важна — пропускането на която и да е от тях води до невъзможност за изпращане на push известия до устройството.
Първата стъпка е приложението да поиска от потребителя разрешение за изпращане на известия чрез UNUserNotificationCenter.current().requestAuthorization. Потребителят може да се съгласи, да откаже или да избере опционални опции (alert, badge, sound). Без изричното съгласие на потребителя системата няма да издаде Device Token, дори ако приложението извика registerForRemoteNotifications. След получаване на разрешение приложението извиква UIApplication.shared.registerForRemoteNotifications(), което инициира процеса на регистрация в APNS.
След регистрация APNS връща токена чрез делегата AppDelegate: application(_:didRegisterForRemoteNotificationsWithDeviceToken:). Успешното извикване съдържа обект Data с токена, който трябва да се конвертира в hex низ за предаване на сървъра. В случай на грешка системата извиква application(_:didFailToRegisterForRemoteNotificationsWithError:) с описание на проблема: неправилна конфигурация на сертификати, липса на мрежа или неправилна конфигурация на проекта.
След получаване на токена приложението трябва незабавно да го предаде на своя сървър за съхранение в базата данни. API заявката включва токена, идентификатор на устройството (за съпоставяне), среда (sandbox/production) и опционално допълнителни данни: версия на ОС, модел на устройството, език. Препоръчва се да повтаряте предаването на токена при всяко стартиране на приложението, така че сървърът винаги да има актуален токен.
// Заявка за разрешение и регистрация в APNS
func registerForPushNotifications() {
UNUserNotificationCenter.current()
.requestAuthorization(options: [.alert, .sound, .badge]) {
[weak self] granted, error in
guard granted else {
print("Разрешението не е получено")
return
}
DispatchQueue.main.async {
UIApplication.shared
.registerForRemoteNotifications()
}
}
}
// Получаване на Device Token от APNS
func application(
_ application: UIApplication,
didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data
) {
let tokenString = deviceToken
.map { String(format: "%02.2hhx", $0) }
.joined()
print("Device Token: \(tokenString)")
// Изпращане на токена до сървъра
PushTokenService.shared
.sendTokenToServer(tokenString) { success in
if success {
UserDefaults.standard.set(tokenString,
forKey: "lastDeviceToken")
}
}
}
Сървърната част на push системата трябва да съхранява Device Token в базата данни, асоцииран с потребителя и средата. При изпращане на известие сървърът формира заявка към APNS, включвайки токена в URL адреса и JWT токен (или сертификат) за авторизация. Коректното управление на токените критично влияе върху процента на доставка на push известия.
Таблицата с токени на сървъра трябва да съдържа най-малко: Device Token (уникален), идентификатор на потребителя, среда (sandbox/production), дата на последно обновяване и статус (активен/неактивен). Препоръчва се да добавите индекс по токен за бързо търсене при изпращане и по потребител за получаване на списък с всички устройства на потребителя. Много приложения позволяват на един потребител да има няколко устройства — всяко със свой токен.
За да изпрати push известие, сървърът трябва да авторизира заявката към APNS по два начина. Certificate-based използва SSL сертификат, генериран в Apple Developer Console. Token-based използва JWT (JSON Web Token) с .p8 ключ, който е валиден до 30 дни без необходимост от обновяване на сертификата. Токен-базираната авторизация се счита за по-модерна и се препоръчва от Apple за нови проекти.
Заявката към APNS включва HTTP/2 метод POST, URL с път /3/device/{device_token}, заглавки за авторизация и JSON тяло с payload. Заглавката apns-topic задължително съдържа bundle ID на приложението. apns-priority указва приоритет на доставка (5 — незабавно, 10 — пестене на батерия). apns-expiration задава време в секунди от епохата, до което APNS ще се опитва да достави известието.
// Пример за изпращане на push чрез Node.js през APNS HTTP/2
const http2 = require('http2');
const client = http2.connect('https://api.push.apple.com');
const deviceToken = 'abcdef0123456789...';
const payload = JSON.stringify({
"aps": { "alert": "Hello!", "sound": "default" }
});
const req = client.request({
':method': 'POST',
':path': `/3/device/${deviceToken}`,
'apns-topic': 'com.example.app',
'apns-priority': '10',
'apns-expiration': '0',
'authorization': `bearer ${jwtToken}`
});
req.write(payload);
req.end();
req.on('отговор', (headers) => {
if (headers[':status'] === '200') {
console.log('Push изпратен успешно');
}
});
При изпращане на push известия до голям брой устройства използвайте пакетно изпращане с контрол на скоростта. APNS препоръчва да не надвишавате 1500 заявки в секунда на една връзка. При превишаване на лимита сървърът на Apple връща грешка 429 Too Many Requests. За мащабни изпращания използвайте няколко връзки и разпределяйте натоварването равномерно по устройства.
Device Token не е постоянен и може да се промени в няколко сценария, което изисква от сървъра механизъм за обновяване. Ако сървърът продължава да изпраща push към остарял токен, APNS връща грешка 410 Gone, указвайки, че токенът вече не е валиден за дадената среда.
Apple документира няколко сценария, при които Device Token се променя: потребителят преинсталира приложението, възстановява устройството от iCloud резервно копие, инсталира нова версия на iOS, както и при нулиране на мрежови или поверителни настройки. Във всеки случай приложението при следващото си стартиране получава нов токен от APNS. Сървърът трябва да обнови токена в базата данни, като премахне стария и запази новия.
Когато сървърът изпраща push към остарял токен, APNS връща HTTP 410 със заглавка apns-unless-timestamp. Тази заглавка указва времето, след което токенът е станал невалиден. Сървърът трябва незабавно да премахне или деактивира този токен в базата данни, за да не изпраща повторно към него. Игнорирането на грешка 410 води до загуба на ресурси и намаляване на процента на доставка.
За поддържане на базата данни с токени в актуално състояние се препоръчва периодично почистване. Скриптът за почистване анализира APNS логовете от последните N дни, намира всички токени, за които е получена грешка 410, и ги деактивира в базата данни. Допълнително могат да се премахват токени, за които не е имало потребителска активност повече от 90 дни — това са безполезни записи, които само увеличават размера на базата данни.
Преди масово изпращане на push известия (разискване, промо кампания) се препоръчва предварително да проверите актуалността на токените. APNS не предоставя директен API за batch валидация на токени, затова се използва стратегия за изпращане на тестов push с нисък приоритет и анализ на грешките. Токените, върнали грешка 410, се изключват от основното изпращане.
Нека разгледаме пълния цикъл на получаване на Device Token в Swift, включително обработка на грешки и предаване към сървъра. Кодът обхваща искане на разрешение, регистрация в APNS, конвертиране на Data в hex низ, обработка на грешки и изпращане на токена до вашия сървър с повторни опити при неуспех.
import UIKit
import UserNotifications
final class PushNotificationManager: NSObject {
static let shared = PushNotificationManager()
private let apiClient = APIClient()
private var currentToken: String?
func register() {
UNUserNotificationCenter.current()
.requestAuthorization(
options: [.alert, .badge, .sound]) {
[weak self] granted, error in
guard granted else {
Analytics.log(
"Push permission denied")
return
}
DispatchQueue.main.async {
UIApplication.shared
.registerForRemoteNotifications()
}
}
}
func handleDeviceToken(_ tokenData: Data) {
let token = tokenData
.map { String(format: "%02.2hhx", $0) }
.joined()
guard token != currentToken else { return }
currentToken = token
sendTokenToServer(token)
}
func handleRegistrationError(_ error: Error) {
Analytics.log(
"Push registration failed: \(error)")
// Повторен опит след закъснение при мрежови грешки
if let urlError = error as? URLError,
urlError.code == .notConnectedToInternet {
DispatchQueue.main.asyncAfter(
deadline: .now() + 10) { [weak self] in
self?.register()
}
}
}
private func sendTokenToServer(_ token: String) {
let body = PushTokenRequest(
token: token,
environment: Environment.current == .debug
? "sandbox" : "production",
osVersion: UIDevice.current.systemVersion,
locale: Locale.current.identifier
)
apiClient.sendToken(body) { [weak self] result in
if case .success = result {
self?.currentToken = token
}
}
}
}
Грешките при регистрация в APNS могат да бъдат причинени от различни фактори. Най-честите са: липса на мрежа, неправилна конфигурация на сертификати в Xcode (например деактивиран capability Push Notifications), използване на симулатор (който не поддържа push) или неправилен provisioning profile. В production е важно да логирате грешките и, при възможност, да повторите регистрацията при следващото стартиране на приложението.
iOS Simulator не поддържа получаване на реален Device Token. За тестване на регистрацията на симулатор използвайте i386-архитектурни проверки: в debug сборка можете да симулирате получаване на токен или да използвате UI тестове с mock обекти. Реалното тестване на push известия винаги се извършва на физическо устройство, свързано към Xcode.
Често задавани въпроси
Да, Device Token може да се промени при преинсталиране на приложението, възстановяване на устройството от резервно копие или обновяване на iOS. Сървърът трябва да обработва обновявания на токените: при получаване на нов токен от познато устройство — заменяйте стария, при грешка 410 — премахвайте токена от базата данни.
Device Token е 32-байтов hex низ от 64 символа в малки букви (0–9, a–f). Пример: „a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2“. Токенът се предава като Data от APNS и се конвертира в низ от страна на приложението.
Sandbox токен се издава за приложения, изградени с разработчески provisioning profile, и работи само с api.sandbox.push.apple.com. Production токен — за App Store и TestFlight, работи с api.push.apple.com. Сървърът трябва да различава средите и да изпраща push към съответния APNS endpoint.
Грешка 410 Gone означава, че Device Token е невалиден. Сървърът трябва незабавно да премахне този токен от базата данни и да спре опитите за изпращане към него. Заглавката apns-unless-timestamp в отговора указва от кога токенът е престанал да работи.
Проверете дали делегат методът application(_:didRegisterForRemoteNotificationsWithDeviceToken:) в AppDelegate се извиква. Ако методът се извиква — токенът е получен. Използвайте debugging логове или OSLog за извеждане на токена в Xcode конзолата. На физическо устройство проверете дали токенът се изпраща до сървъра чрез Network Link Conditioner.
Обобщение
Ще разработим мобилно приложение под ключ
IT Sectr създава iOS и Android приложения за стартъпи и бизнеси от 2017 г. Ще ви консултираме и ще предложим най-доброто решение.
Прочетете също