Что такое Push-токен (Device Token) в iOS?

«Что такое Push-токен (Device Token) в iOS?» — вопрос из категории Сети, который задают на 10% собеседований IOS Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Push-токен (Device Token) — это уникальный криптографически сгенерированный идентификатор, который сервер Apple Push Notification service (APNs) выдает устройству для целевой доставки push-уведомлений. Это адрес вашего приложения на конкретном устройстве.

Как это работает:

  1. Приложение запрашивает разрешение на уведомления и регистрируется в APNs.
  2. Система генерирует токен и возвращает его приложению.
  3. Приложение отправляет этот токен вашему серверу.
  4. Ваш сервер, желая отправить уведомление, обращается к APNs, указывая этот токен и payload уведомления.
  5. APNs находит устройство по токену и доставляет уведомление.

Ключевые характеристики:

  • Уникальность: Токен уникален для связки приложение-устройство.
  • Изменчивость: Токен может измениться после:
    • Переустановки приложения.
    • Восстановления устройства из резервной копии.
    • Обновления iOS.
    • Сброса настроек конфиденциальности.
    • Поэтому сервер должен его периодически обновлять.
  • Формат: Токен приходит как Data (бинарный объект), его необходимо преобразовать в строку для передачи на сервер.

Пример получения и обработки токена:

import UserNotifications

class AppDelegate: UIResponder, UIApplicationDelegate {

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        requestPushNotificationPermission()
        return true
    }

    private func requestPushNotificationPermission() {
        let center = UNUserNotificationCenter.current()
        center.requestAuthorization(options: [.alert, .sound, .badge]) { granted, error in
            if granted {
                DispatchQueue.main.async {
                    // Запрашиваем токен только после получения разрешения
                    UIApplication.shared.registerForRemoteNotifications()
                }
            }
        }
    }

    // УСПЕХ: Система успешно зарегистрировала устройство в APNs.
    func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
        // 1. Конвертируем Data в строку (стандартный способ)
        let tokenString = deviceToken.map { String(format: "%02.2hhx", $0) }.joined()
        print("APNs Device Token: (tokenString)")

        // 2. Отправляем токен на ваш бэкенд-сервер
        sendTokenToServer(tokenString)
    }

    // ОШИБКА: Не удалось зарегистрироваться в APNs.
    func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
        print("Failed to register for remote notifications: (error)")
    }

    private func sendTokenToServer(_ token: String) {
        guard let url = URL(string: "https://your-backend.com/register-device") else { return }
        var request = URLRequest(url: url)
        request.httpMethod = "POST"
        let body = ["deviceToken": token, "platform": "ios"]
        request.httpBody = try? JSONSerialization.data(withJSONObject: body)
        // ... выполняем сетевой запрос
    }
}

Важно: Начиная с iOS 13, APNs использует токены в формате HTTP/2, которые могут быть длиннее 64 байт. Не стоит делать предположений о фиксированной длине токена.