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), истекао је или је опозван, Аплов сервер враћа грешку 410 Gone или 400 BadRequest. Тек након успешне валидације токена, APNS започиње испоруку обавештења на уређај.
Device Token не треба мешати са IDFA-ом (идентификатором за оглашиваче), IDFV-ом (идентификатором за продавца) или UID-ом (јединственим идентификатором уређаја). IDFA и IDFV се користе за оглашивање и аналитику, UID је хардверски серијски број. Device Token постоји искључиво за push обавештења и не открива информације о кориснику или уређају изван APNS-а.
| Идентификатор | Намена | Постојаност |
|---|---|---|
| Device Token | Усмеравање push обавештења APNS | Може се променити |
| 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 са .p8 кључем који важи до 30 дана без потребе за ажурирањем цертификата. Ауторизација на бази токена сматра се модернијом и Апл је препоручује за нове пројекте.
Захтев према APNS-у укључује HTTP/2 POST метод, URL са путањем /3/device/{device_token}, заглавље ауторизације и JSON тело са payload-ом. Заглавље apns-topic обавезно садржи bundle ID апликације. apns-priority одређује приоритет испоруке (5 — одмах, 10 — уштеда батерије). apns-expiration поставља време у секундама од epoch до којег ће 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('response', (headers) => {
if (headers[':status'] === '200') {
console.log('Push sent successfully');
}
});
При слању push обавештења на велики број уређаја, користите серијско слање са контролом брзине. APNS препоручује да не прелазите 1500 захтева у секунди по једној вези. При прекорању лимита, Аплов сервер враћа грешку 429 Too Many Requests. За велике пошиљке користите више веза и равномерно распоређујте оптерећење на уређаје.
Device Token није сталан и може се променити у неколико сценарија, што захтева механизам ажурирања на серверу. Ако сервер настави да шаље push на застарели токен, APNS враћа грешку 410 Gone, наводећи да токен више није важећи за дато окружење.
Апл документује неколико сценарија у којима се Device Token мења: корисник поново инсталира апликацију, враћа уређај из iCloud бекапа, инсталира нову верзију iOS, као и при ресетовању мрежних подешавања или приватности. У сваком случају, апликација ће при следећем покретању добити нови токен од APNS-а. Сервер мора да ажурира токен у бази података, обришућући стари и чувајући нови.
Када сервер шаље push на застарели токен, APNS враћа HTTP 410 са заглављем apns-unless-timestamp. Ово заглавље показује време након којег је токен постао неважећи. Сервер мора одмах да обрише или деактивира овај токен у бази података да не би поново слао на њега. Игнорисање грешке 410 доводи до расипања ресурса и смањења стопе испоруке.
За одржавање базе токена ажурираном, препоручује се покретање периодичног чишћења. Скрипта за чишћење анализира APNS логове за последњих N дана, проналази све токене на које је примљена грешка 410 и деактивира их у бази података. Додатно, могу се обрисати токени без корисничке активности дуже од 90 дана — то су бескорисни записи који само повећавају величину базе података.
Пре масовног слања push обавештења (билтен, промо кампања), препоручује се претходно проверити ажурност токена. APNS не пружа директан API за групну валидацију токена, па се користи стратегија слања тестног 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. У продукцији је важно логовати грешке и, ако је могуће, поновити регистрацију при следећем покретању апликације.
iOS симулатор не подржава добијање правог 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. године. Саветоваћемо вас и предложити најбоље решење.
Прочитајте такође