Device Token to unikalny identyfikator, który APNS przypisuje każdemu urządzeniu iOS do routowania powiadomień push. Token jest generowany przez system podczas rejestracji aplikacji do otrzymywania powiadomień i musi zostać przekazany na serwer, aby wysyłać push na to konkretne urządzenie. Według Apple Developer Documentation, 2026, Device Token może się zmienić przy ponownej instalacji aplikacji, przywracaniu urządzenia z kopii zapasowej lub aktualizacji iOS, dlatego serwer powinien regularnie aktualizować tokeny, aby zapewnić dostarczanie.
Najważniejsze
Device Token (token urządzenia) to unikalny identyfikator w postaci hex-stringa, który APNS (Apple Push Notification Service) generuje dla każdej aplikacji na urządzeniu iOS. Token jest kluczem, po którym serwer wysyła powiadomienia push na konkretne urządzenie. Bez poprawnego Device Token serwer nie może dostarczyć push — APNS odrzuca żądzenie z błędem 400 BadRequest.
Device Token jest tworzony przez system iOS przy pierwszym kontakcie aplikacji z APNS po instalacji. Proces generacji obejmuje kryptograficzne powiązanie identyfikatora aplikacji (bundle ID) i unikalnego identyfikatora urządzenia (UID), po czym APNS zwraca aplikacji 32-bajtowy token w formacie hex (64 znaki). Token nie jest stały — system może wygenerować nowy w określonych warunkach.
Gdy serwer wysyła powiadomienie push, dołącza Device Token w żądaniu HTTP/2 do APNS. APNS sprawdza ważność tokena: jeśli token dotyczy innego środowiska (sandbox zamiast production), wygasł lub został unieważniony, serwer Apple zwraca błąd 410 Gone lub 400 BadRequest. Dopiero po pomyślnej walidacji tokena APNS rozpoczyna dostarczanie powiadomienia na urządzenie.
Device Token nie należy mylić z IDFA (Identifier for Advertisers), IDFV (Identifier for Vendor) ani UID (Unique Device Identifier). IDFA i IDFV są używane do reklam i analityki, UID — sprzętowy numer seryjny. Device Token istnieje wyłącznie dla powiadomień push i nie ujawnia informacji o użytkowniku ani urządzeniu poza APNS.
| Identyfikator | Przeznaczenie | Stałość |
|---|---|---|
| Device Token | Routowanie powiadomień push APNS | Może się zmienić |
| IDFA | Reklamy i śledzenie | Resetowany przez użytkownika |
| IDFV | Identyfikacja dostawcy (analityka) | Stały dla aplikacji jednego dewelopera |
| Bundle ID | Unikalny identyfikator aplikacji | Stały |
Proces uzyskiwania Device Token składa się z kilku obowiązkowych kroków, począwszy od prośby o zgodę od użytkownika, a skończywszy na przekazaniu tokena na serwer. Każdy krok jest krytycznie ważny — pominięcie któregokolwiek prowadzi do niemożliwości wysyłania powiadomień push na urządzenie.
Pierwszym krokiem aplikacja prosi użytkownika o zgodę na wysyłanie powiadomień przez UNUserNotificationCenter.current().requestAuthorization. Użytkownik może wyrazić zgodę, zabronić lub wybrać opcjonalne opcje (alert, badge, sound). Bez wyraźnej zgody użytkownika system nie wyda Device Token, nawet jeśli aplikacja wywoła registerForRemoteNotifications. Po uzyskaniu zgody aplikacja wywołuje UIApplication.shared.registerForRemoteNotifications(), co inicjuje proces rejestracji w APNS.
Po rejestracji APNS zwraca token przez delegata AppDelegate: application(_:didRegisterForRemoteNotificationsWithDeviceToken:). Pomyślne wywołanie zawiera obiekt Data z tokenem, który należy skonwertować na hex-string do przekazania na serwer. W przypadku błędu system wywołuje application(_:didFailToRegisterForRemoteNotificationsWithError:) z opisem problemu: nieprawidłowa konfiguracja certyfikatów, brak sieci lub nieprawidłowa konfiguracja projektu.
Po otrzymaniu tokena aplikacja powinna natychmiast przekazać go na swój serwer w celu zapisania w bazie danych. Żadanie API zawiera token, identyfikator urządzenia (do mapowania), środowisko (sandbox/production) i opcjonalnie dodatkowe dane: wersję systemu, model urządzenia, język. Zaleca się powtarzanie przekazywania tokena przy każdym uruchomieniu aplikacji, aby serwer zawsze miał aktualny token.
// Żadanie uprawnień i rejestracja w APNS
func registerForPushNotifications() {
UNUserNotificationCenter.current()
.requestAuthorization(options: [.alert, .sound, .badge]) {
[weak self] granted, error in
guard granted else {
print("Uprawnienie nie przyznane")
return
}
DispatchQueue.main.async {
UIApplication.shared
.registerForRemoteNotifications()
}
}
}
// Otrzymanie Device Token z APNS
func application(
_ application: UIApplication,
didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data
) {
let tokenString = deviceToken
.map { String(format: "%02.2hhx", $0) }
.joined()
print("Device Token: \(tokenString)")
// Wysyłanie tokena na serwer
PushTokenService.shared
.sendTokenToServer(tokenString) { success in
if success {
UserDefaults.standard.set(tokenString,
forKey: "lastDeviceToken")
}
}
}
Część serwerowa systemu push powinna przechowywać Device Token w bazie danych, powiązany z użytkownikiem i środowiskiem. Przy wysyłaniu powiadomienia serwer tworzy żądanie do APNS, dołączając token w URL i JWT-token (lub certyfikat) do autoryzacji. Prawidłowe zarządzanie tokenami krytycznie wpływa na procent dostarczania powiadomień push.
Tabela tokenów na serwerze powinna zawierać co najmniej: Device Token (unikalny), identyfikator użytkownika, środowisko (sandbox/production), datę ostatniej aktualizacji i status (aktywny/nieaktywny). Zaleca się dodanie indeksu po tokenie do szybkiego wyszukiwania przy wysyłaniu i po użytkowniku do uzyskania listy wszystkich urządzeń użytkownika. Wiele aplikacji pozwala jednemu użytkownikowi mieć kilka urządzeń — każde z własnym tokenem.
Aby wysłać powiadomienie push, serwer musi autoryzować żądanie do APNS na dwa sposoby. Certificate-based używa certyfikatu SSL wygenerowanego w Apple Developer Console. Token-based używa JWT (JSON Web Token) z kluczem .p8, który działa do 30 dni bez konieczności aktualizacji certyfikatu. Autoryzacja token-bazowana jest uważana za bardziej nowoczesną i zalecana przez Apple dla nowych projektów.
Żadanie do APNS obejmuje HTTP/2 metodę POST, URL ze ścieżką /3/device/{device_token}, nagłówki autoryzacji i JSON-body z payloadem. Nagłówek apns-topic obowiązkowo zawiera bundle ID aplikacji. apns-priority określa priorytet dostarczenia (5 — natychmiast, 10 — oszczędzanie baterii). apns-expiration określa czas w sekundach od epoki, do którego APNS będzie próbować dostarczyć powiadomienie.
// Przykład wysyłania push na Node.js przez 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');
}
});
Przy wysyłaniu powiadomień push na dużą liczbę urządzeń używaj wysyłania wsadowego z kontrolą prędkości. APNS zaleca nieprzekraczanie 1500 żądań na sekundę na jedno połączenie. Po przekroczeniu limitu serwer Apple zwraca błąd 429 Too Many Requests. Do masowych wysyłek używaj kilku połączeń i rozkładaj obciążenie na urządzenia równomiernie.
Device Token nie jest stały i może się zmienić w kilku scenariuszach, co wymaga od serwera mechanizmu aktualizacji. Jeśli serwer kontynuuje wysyłanie push na nieaktualny token, APNS zwraca błąd 410 Gone, wskazując, że token nie jest już ważny dla danego środowiska.
Apple dokumentuje kilka scenariuszy, w których Device Token się zmienia: użytkownik ponownie instaluje aplikację, przywraca urządzenie z kopii zapasowej iCloud, instaluje nową wersję iOS, a także przy resecie ustawień sieciowych lub prywatności. W każdym przypadku aplikacja przy następnym uruchomieniu otrzyma nowy token z APNS. Serwer powinien zaktualizować token w bazie danych, usuwając stary i zapisując nowy.
Gdy serwer wysyła push na nieaktualny token, APNS zwraca HTTP 410 z nagłówkiem apns-unless-timestamp. Ten nagłówek wskazuje czas, po którym token stał się nieważny. Serwer powinien natychmiast usunąć lub dezaktywować ten token w bazie danych, aby nie wysyłać na niego ponownie. Ignorowanie błędu 410 prowadzi do marnowania zasobów i obniżenia wskaźnika dostarczalności.
Aby utrzymać bazę tokenów w aktualnym stanie, zaleca się uruchamianie okresowego czyszczenia. Skrypt czyszczenia analizuje logi APNS z ostatnich N dni, znajduje wszystkie tokeny, na które otrzymano błąd 410, i dezaktywuje je w bazie danych. Dodatkowo można usuwać tokeny, po których nie było aktywności użytkownika przez ponad 90 dni — to bezużyteczne rekordy, które tylko zwiększają rozmiar bazy danych.
Przed masową wysyłką powiadomień push (newsletter, kampania promocyjna) zaleca się wstępne sprawdzenie aktualności tokenów. APNS nie udostępnia bezpośredniego API do wsadowej walidacji tokenów, dlatego stosuje się strategię wysyłania testowego push z niskim priorytetem i analizę błędów. Tokeny, które zwróciły błąd 410, są wykluczane z głównej wysyłki.
Rozważmy pełny cykl uzyskiwania Device Token w Swift, w tym obsługę błędów i przekazanie na serwer. Kod obejmuje prośbę o zgodę, rejestrację w APNS, konwersję Data na hex-string, obsługę błędów i wysyłanie tokena na własny serwer z ponownymi próbami przy niepowodzeniu.
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)")
// Ponawianie po opóźnieniu przy błędach sieciowych
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
}
}
}
}
Błędy podczas rejestracji w APNS mogą być spowodowane różnymi przyczynami. Najczęstsze — brak sieci, nieprawidłowa konfiguracja certyfikatów w Xcode (np. wyłączona capability Push Notifications), używanie symulatora (który nie obsługuje push) lub nieprawidłowy provisioning profile. W produkcji ważne jest logowanie błędów i, jeśli to możliwe, ponawianie rejestracji przy następnym uruchomieniu aplikacji.
iOS Simulator nie obsługuje otrzymywania rzeczywistego Device Token. Do testowania rejestracji na symulatorze używaj sprawdzeń architektury i386: w kompilacji debug można symulować otrzymanie tokena lub używać testów UI z obiektami mock. Rzeczywiste testowanie powiadomień push zawsze wykonuje się na fizycznym urządzeniu podłączonym do Xcode.
Często zadawane pytania
Tak, Device Token może się zmienić przy ponownej instalacji aplikacji, przywracaniu urządzenia z kopii zapasowej lub aktualizacji iOS. Serwer powinien obsługiwać aktualizacje tokenów: przy otrzymaniu nowego tokena od znanego urządzenia — zastępować stary, przy błędzie 410 — usuwać token z bazy.
Device Token to 32-bajtowy hex-string z 64 znaków małymi literami (0–9, a–f). Przykład: "a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2". Token jest przesyłany jako Data z APNS i konwertowany na string po stronie aplikacji.
Token sandbox jest wydawany dla aplikacji zbudowanych z developerskim provisioning profile i działa tylko z api.sandbox.push.apple.com. Token production — dla App Store i TestFlight, działa z api.push.apple.com. Serwer powinien rozróżniać środowiska i wysyłać push na odpowiedni endpoint APNS.
Błąd 410 Gone oznacza, że Device Token jest nieważny. Serwer powinien natychmiast usunąć ten token z bazy danych i zaprzestać prób wysyłania na niego. Nagłówek apns-unless-timestamp w odpowiedzi wskazuje, od kiedy token przestał działać.
Sprawdź wywołanie delegata application(_:didRegisterForRemoteNotificationsWithDeviceToken:) w AppDelegate. Jeśli metoda jest wywoływana — token został otrzymany. Używaj debugowania lub OSLog do wypisania tokena w konsoli Xcode. Na fizycznym urządzeniu sprawdź, czy token jest wysyłany na serwer przez Network Link Conditioner.
Podsumowanie
Opracujemy aplikację mobilną pod klucz
IT Sectr tworzy aplikacje na iOS i Androida dla startupów i firm od 2017 roku. Doradzimy Ci i zaproponujemy najlepsze rozwiązanie.
Przeczytaj również