Интеграция push-уведомлений через Apple Push Notification Service (APNs)

TRUETECH занимается разработкой, поддержкой и обслуживанием мобильных приложений iOS, Android, PWA. Имеем большой опыт и экспертизу для публикации мобильных приложений в популярные маркеты Google Play, App Store, Amazon, AppGallery и другие.
Разработка и поддержка любых видов мобильных приложений:
Информационные и развлекательные мобильные приложения
Новостные приложения, игры, справочники, онлайн-каталоги, погодные, фитнес и здоровье, туристические, образовательные, социальные сети и мессенджеры, квиз, блоги и подкасты, форумы, агрегаторы
Мобильные приложения электронной коммерции
Интернет-магазины, B2B-приложения, маркетплейсы, онлайн-обменники, кэшбэк-сервисы, биржи, дропшиппинг-платформы, программы лояльности, доставка еды и товаров, платежные системы
Мобильные приложения для управления бизнес-процессами
CRM-системы, ERP-системы, управление проектами, инструменты для команды продаж, учет финансов, управление производством, логистика и доставка, управление персоналом, системы мониторинга данных
Мобильные приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, платформы предоставления электронных услуг, платформы кешбека, видеохостинги, тематические порталы, платформы онлайн-бронирования и записи, платформы онлайн-торговли

Это лишь некоторые из типы мобильных приложений, с которыми мы работаем, и каждый из них может иметь свои специфические особенности и функциональность, а также быть адаптированным под конкретные потребности и цели клиента.

Предлагаемые услуги
Показано 1 из 1 услугВсе 1735 услуг
Интеграция push-уведомлений через Apple Push Notification Service (APNs)
Средняя
от 1 рабочего дня до 3 рабочих дней
Часто задаваемые вопросы
Наши компетенции:
Этапы разработки
Последние работы
  • image_mobile-applications_feedme_467_0.webp
    Разработка мобильного приложения для компании FEEDME
    756
  • image_mobile-applications_xoomer_471_0.webp
    Разработка мобильного приложения для компании XOOMER
    624
  • image_mobile-applications_rhl_428_0.webp
    Разработка мобильного приложения для компании RHL
    1054
  • image_mobile-applications_zippy_411_0.webp
    Разработка мобильного приложения для компании ZIPPY
    947
  • image_mobile-applications_affhome_429_0.webp
    Разработка мобильного приложения для компании Affhome
    862
  • image_mobile-applications_flavors_409_0.webp
    Разработка мобильного приложения для компании FLAVORS
    445

Интеграция push-уведомлений через Apple Push Notification Service (APNs)

Push-уведомления в iOS выглядят как несложная задача ровно до момента, когда уведомления доходят на симулятор, но не на реальное устройство. Или приходят в дев-окружении и пропадают в продакшене. Причина почти всегда одна: неправильная конфигурация сертификатов или несоответствие окружения (sandbox vs production). APNs — строгая система, и любое несоответствие конфигурации приводит к молчаливой потере уведомлений без ошибки на клиенте.

Настройка: p8 ключ vs p12 сертификат

Apple поддерживает два способа аутентификации для APNs:

APNs Auth Key (.p8) — JWT-токен. Один ключ на весь аккаунт, не истекает (только если не отозвать), работает для sandbox и production без переключения. Это рекомендуемый способ с 2016 года.

APNs Certificate (.p12) — SSL-сертификат. Истекает через год, отдельный для sandbox и production, привязан к конкретному Bundle ID. Устаревший способ, но ещё встречается в legacy проектах.

Для нового проекта всегда выбираем .p8 через Apple Developer Console → Certificates, Identifiers & Profiles → Keys.

Конфигурация на стороне iOS-приложения

// AppDelegate.swift
func application(_ application: UIApplication,
                 didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

    UNUserNotificationCenter.current().delegate = self

    let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound]
    UNUserNotificationCenter.current().requestAuthorization(options: authOptions) { granted, error in
        guard granted else { return }
        DispatchQueue.main.async {
            UIApplication.shared.registerForRemoteNotifications()
        }
    }
    return true
}

func application(_ application: UIApplication,
                 didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
    let tokenString = deviceToken.map { String(format: "%02.2hhx", $0) }.joined()
    // Отправляем token на сервер
    NotificationService.shared.registerToken(tokenString)
}

func application(_ application: UIApplication,
                 didFailToRegisterForRemoteNotificationsWithError error: Error) {
    print("APNs registration failed: \(error)")
}

didFailToRegisterForRemoteNotificationsWithError — этот метод многие забывают реализовать. Без него молчаливый сбой регистрации никак не логируется.

Capabilities и Entitlements

В Xcode: Target → Signing & Capabilities → + Capability → Push Notifications. Это добавляет aps-environment в .entitlements. Значение — development для debug, production для release. Несоответствие этого значения при отправке уведомления — самая частая причина BadDeviceToken ошибки от APNs.

Также добавляем Background Modes → Remote notifications, если нужна фоновая обработка.

Типы payload

Стандартный alert:

{
  "aps": {
    "alert": {
      "title": "Новое сообщение",
      "body": "Иван написал вам"
    },
    "badge": 3,
    "sound": "default"
  },
  "userId": "u123",
  "messageId": "m456"
}

Silent push (фоновое обновление без UI):

{
  "aps": {
    "content-available": 1
  },
  "syncType": "messages"
}

Silent push требует Background Modes → Remote notifications в Capabilities. На iOS 13+ Apple ограничивает количество silent push до ~3 в час — нельзя использовать как замену polling.

Notification Service Extension

Для модификации уведомлений перед показом (расшифровка, загрузка изображения) — NotificationServiceExtension. Отдельный таргет в Xcode, обрабатывает уведомления с mutable-content: 1 в payload:

class NotificationService: UNNotificationServiceExtension {
    override func didReceive(_ request: UNNotificationRequest,
                             withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
        guard let bestAttempt = request.content.mutableCopy() as? UNMutableNotificationContent,
              let attachmentURL = request.content.userInfo["imageUrl"] as? String,
              let url = URL(string: attachmentURL) else {
            contentHandler(request.content)
            return
        }

        // Загружаем изображение и прикрепляем
        downloadAttachment(from: url) { attachment in
            if let attachment { bestAttempt.attachments = [attachment] }
            contentHandler(bestAttempt)
        }
    }
}

Таймаут Extension — 30 секунд. Если не успели — APNs показывает оригинальное уведомление.

Токен и его жизненный цикл

Device token меняется: при переустановке приложения, при восстановлении из бэкапа, иногда при обновлении iOS. Сервер должен обновлять токен при каждом didRegisterForRemoteNotificationsWithDeviceToken. APNs возвращает 410 Gone при отправке на устаревший токен — сервер должен его удалять.

Отладка

  • Simulator: APNs работает только на физических устройствах (до Xcode 11.4 вообще не работал, с 11.4+ — через .apns файл в симуляторе)
  • Console.app: фильтр по dasd и apsd процессам — там логи APNs daemon
  • Instruments → Push Notifications: трекинг delivery

Что входит в работу

  • Настройка APNs Auth Key (.p8) в Apple Developer Console
  • Capabilities и Entitlements в Xcode
  • Регистрация, получение токена, обработка lifecycle токена
  • Обработка foreground / background / terminated состояний
  • Notification Service Extension для rich notifications
  • Silent push для фоновой синхронизации
  • Интеграция с backend для хранения и отправки токенов

Сроки

Базовая интеграция APNs с alert-уведомлениями: 1 день. С rich notifications, silent push, Extension и полным lifecycle токена: 2–3 дня.