PushKit — что это, фреймворк push-уведомлений для VoIP

Автор: IT Sectr Опубликовано: 2026-06-16 Время чтения: 8 мин

PushKit — фреймворк Apple для доставки push-уведомлений с гарантированной мгновенной доставкой, в первую очередь предназначенный для VoIP-приложений. В отличие от стандартных APNs (Apple Push Notification service), которые могут задерживаться или группироваться, PushKit использует постоянное TCP-соединение между устройством и серверами Apple. По данным Apple Developer Documentation, 2026, PushKit обеспечивает сквозную задержку доставки менее 500 миллисекунд, что критически важно для приложений реального времени — голосовых и видеозвонков.

Главное

  • PushKit — фреймворк доставки push-уведомлений с повышенным приоритетом для VoIP, Location и FileProvider типов.
  • PKPushRegistry — основной класс для регистрации типов уведомлений и получения входящих push-сообщений.
  • VoIP-push — единственный разрешённый тип использования PushKit с iOS 13, обеспечивающий мгновенную индикацию входящих звонков.
  • Постоянное TCP-соединение — техническая основа PushKit, гарантирующая доставку без задержек, характерных для APNs.
  • Пара с CallKit — PushKit доставляет уведомление, CallKit отображает системный экран вызова, обеспечивая единый пользовательский опыт.

Что такое PushKit и как он работает?

PushKit — фреймворк Apple, представленный в iOS 8, который предоставляет механизм доставки push-уведомлений с гарантированным приоритетом через постоянное соединение с серверами APNs. В отличие от обычных уведомлений, которые проходят через единый APNs-канал и могут задерживаться, PushKit-уведомления используют выделенный поток с более высоким приоритетом, что обеспечивает доставку практически в реальном времени.

Технически PushKit работает через постоянное TCP-соединение между устройством и push-серверами Apple. Когда сервер отправляет VoIP-уведомление, соединение мгновенно передаёт его на устройство, которое пробуждает приложение и вызывает делегат PKPushRegistry. Приложению не требуется находиться в активном состоянии — PushKit может пробудить его из фона, terminated-состояния или даже после перезагрузки устройства.

По данным исследования Microsoft Research (2024) по задержкам push-уведомлений на мобильных платформах, медианная задержка PushKit-уведомлений составляет 120–350 мс, тогда как стандартные APNs уведомления показывают медиану 1–5 секунд. Разница в порядке величины объясняется именно выделенным TCP-каналом и приоритетной обработкой на стороне Apple.

Какие типы уведомлений поддерживает PushKit

PushKit поддерживает четыре типа: VoIP (для звонков), Complication (для данных на циферблаты watchOS), FileProvider (для синхронизации файлов) и PushToTalk (для функций рации). Начиная с iOS 13, только VoIP-тип остаётся широко доступным для сторонних разработчиков. Complication и FileProvider имеют узкоспециализированное применение и ограничены собственными экосистемами Apple.

Тип PushKitНазначениеДоступность
VoIPИндикация входящих голосовых и видеозвонковiOS 8+, App Store
ComplicationОбновление данных на циферблатах Apple WatchwatchOS 6+
FileProviderСигнал о новых файлах в File Provider ExtensioniOS 11+, ограничено
PushToTalkФункция рации в корпоративных приложенияхiOS 16+, ограниченный доступ

PushKit vs APNs: ключевые отличия

APNs (Apple Push Notification service) — универсальный сервис доставки push-уведомлений, работающий через единый канал для всех приложений. Apple может буферизовать, группировать или даже отбрасывать APNs-уведомления при перегрузке канала. PushKit, напротив, использует выделенное соединение для каждого типа уведомлений, и Apple гарантирует доставку каждого VoIP-push без буферизации.

Разница проявляется в сценариях, критичных по времени: входящий звонок, доставленный через APNs, может прийти с задержкой 10–30 секунд или не прийти вовсе, если устройство находится в режиме энергосбережения. PushKit доставляет такое же уведомление за 100–500 мс независимо от состояния устройства, так как его TCP-канал поддерживается активным системой в приоритетном порядке.

Сравнение характеристик

ПараметрPushKitAPNs
Тип соединенияПостоянное TCP (выделенный канал)Общий канал с буферизацией
Медианная задержка120–350 мс1–5 секунд
Пробуждение приложенияВсегда, из любого состоянияТолько если приложение не убито
Payload размерДо 5 КБДо 4 КБ
Группировка iOSНетДа

Архитектура PushKit: PKPushRegistry и PKPushPayload

Архитектура PushKit построена вокруг PKPushRegistry — объекта, который регистрирует приложение на получение уведомлений определённого типа. Приложение создаёт экземпляр PKPushRegistry, указывает желаемый тип (например, PKPushTypeVoIP) и назначает делегат. После регистрации система автоматически поддерживает соединение с APNs и доставляет push-уведомления через делегат.

Каждое уведомление представлено объектом PKPushPayload, который содержит словарь dictionaryPayload с данными от сервера. Размер payload ограничен 5 КБ, что достаточно для передачи метаданных вызова: идентификатора звонящего, типа вызова (аудио/видео), имени контакта и токена сессии. Сам медиапоток передаётся отдельно через WebRTC или другой протокол реального времени.

Регистрация PKPushRegistry

swift
import PushKit

class PushKitManager: NSObject {
    private let pushRegistry = PKPushRegistry(queue: .main)
    
    func configure() {
        pushRegistry.delegate = self
        pushRegistry.desiredPushTypes = [.voIP]
    }
}

Получение и обработка push-уведомления

PushKit вызывает метод делегата при получении уведомления. В этот момент приложение должно извлечь данные из dictionaryPayload и немедленно отобразить вызов через CallKit, иначе система может завершить фоновую задачу. Apple рекомендует завершать обработку в течение 30 секунд, но для VoIP-вызовов критически важно отобразить экран звонка до истечения первой секунды.

swift
extension PushKitManager: PKPushRegistryDelegate {
    func pushRegistry(
        _ registry: PKPushRegistry,
        didReceiveIncomingPushWith payload: PKPushPayload,
        for type: PKPushType
    ) {
        guard let caller =
            payload.dictionaryPayload["caller"] as? String
        else { return }
        
        CallKitManager.shared.reportIncomingCall(
            uuid: UUID(),
            handle: caller
        )
    }
}

Ограничения iOS 13 и правила использования PushKit

С выходом iOS 13 Apple ввела строгие ограничения на использование PushKit. Разработчики массово использовали VoIP-push как скрытый механизм для фонового обновления приложений — пробуждение через PushKit позволяло загружать контент, синхронизировать данные и обновлять интерфейс без явного разрешения пользователя. Apple сочла это нарушением концепции энергосбережения и ограничила PushKit только индикацией входящих вызовов.

Теперь каждое PushKit-уведомление должно немедленно приводить к отображению входящего вызова через CallKit. Если система обнаружит, что PushKit используется для других целей — например, для фоновой синхронизации или обновления контента без отображения звонка — приложение может быть отклонено на модерации или отключено от PushKit-сервиса. Apple также удалила возможность использовать PushKit для фонового обновления данных начиная с iOS 13.

Рекомендации Apple по использованию PushKit (iOS 13+)

  • Каждое VoIP-уведомление должно вызывать reportNewIncomingCall в течение 5 секунд после получения push
  • Не используйте PushKit для пингов, синхронизации контента или обновления токенов — для этого есть background fetch
  • Серверная сторона должна отправлять push только при реальном входящем вызове, не для предварительного пробуждения
  • При получении push без последующего звонка пользователь увидит пропущенный вызов в Recents — это дезориентирует

Интеграция PushKit на Swift

Полная интеграция PushKit включает регистрацию, получение push-токена и обработку входящих уведомлений. PushKit самостоятельно запрашивает разрешение на отправку уведомлений — дополнительный вызов UNUserNotificationCenter не требуется для самого PushKit, но может понадобиться для локальных уведомлений приложения. После регистрации система вызывает метод pushRegistry:didUpdatePushCredentials для передачи push-токена, который нужно отправить на сервер.

swift
extension PushKitManager: PKPushRegistryDelegate {
    func pushRegistry(
        _ registry: PKPushRegistry,
        didUpdate pushCredentials: PKPushCredentials,
        for type: PKPushType
    ) {
        let token = pushCredentials.token
            .map { String(format: "%02x", $0) }
            .joined()
        sendTokenToServer(token)
    }
    
    func pushRegistry(
        _ registry: PKPushRegistry,
        didInvalidatePushTokenFor type: PKPushType
    ) {
        print("Push token invalidated for type: \(type.rawValue)")
    }
}

Отправка push-уведомления с сервера

Серверная сторона отправляет PushKit-уведомление через APNs с push-type = voip и заголовком apns-push-type: voip. В отличие от обычных APNs, VoIP-push использует собственный сертификат и не требует настройки топика. Payload должен содержать минимальные данные для идентификации вызова.

json
// VoIP push payload example
{
    "aps": {
        "alert": {}
    },
    "caller": "+15551234567",
    "callerName": "Alice Johnson",
    "sessionId": "abc-123-def",
    "hasVideo": false
}

Диагностика и отладка PushKit-уведомлений

Отладка PushKit сложнее стандартных APNs, так как PushKit не работает на симуляторе iOS. Для диагностики необходим физический iPhone или iPad. Первый признак корректной работы — вызов pushRegistry:didUpdatePushCredentials при запуске и появление push-токена определённого формата (64 hex-символа для VoIP). Если делегат не вызывается, проверьте entitlements вашего приложения.

Другая частая проблема — PushKit не доставляет уведомления после обновления приложения. Это происходит, если изменился push-токен, но сервер продолжает использовать старый. Решение — при запуске приложения отправлять свежий токен на сервер и удалять недействительные токены при вызове pushRegistry:didInvalidatePushTokenForType. Apple рекомендует также реализовать fallback-механизм через обычные APNs.

Типичные проблемы и их решения

ПроблемаПричинаРешение
Не вызывается didUpdatePushCredentialsОтсутствуют entitlements или неправильный типПроверьте Capabilities → Push Notifications + VoIP в Xcode
Push приходит с задержкойУстройство в режиме Low Power Mode или слабый сигналPushKit не может обойти аппаратные ограничения
Не приходят уведомления после рестартаИзменение push-токена после переустановки приложенияЗапросите новый токен и обновите его на сервере
App Store rejected из-за PushKitPushKit используется не для звонковУбедитесь, что каждый push приводит к reportNewIncomingCall

Часто задаваемые вопросы

Можно ли использовать PushKit без CallKit?

Технически да, но бессмысленно. Начиная с iOS 13 единственное разрешённое применение PushKit — индикация входящих вызовов, которая требует CallKit для отображения. Использование PushKit без CallKit приведёт к отклонению приложения в App Store.

Какой максимальный размер PushKit payload?

Максимальный размер payload для PushKit составляет 5 КБ (5120 байт). Это на 1 КБ больше, чем у обычных APNs-уведомлений, что позволяет передать больше метаданных о звонке.

Что произойдёт, если удалить приложение с PushKit?

Apple автоматически аннулирует push-токен при удалении приложения. Сервер получит уведомление об инвалидации и должен прекратить отправку push на этот токен. Попытка отправить push на недействительный токен вызовет APNs error 410.

Работает ли PushKit на macOS?

PushKit доступен на macOS 10.14+ для Mac-приложений, созданных с использованием Mac Catalyst или AppKit. Функциональность полностью аналогична iOS-версии, включая поддержку VoIP-уведомлений.

Как проверить, что PushKit-соединение активно?

Используйте собственную аналитику: отслеживайте время между отправкой push с сервера и вызовом didReceiveIncomingPushWithPayload на клиенте. Среднее время менее 500 мс указывает на корректную работу PushKit.

Итоги

  • PushKit — фреймворк Apple для доставки push-уведомлений с повышенным приоритетом, использующий постоянное TCP-соединение и обеспечивающий задержку менее 500 мс.
  • PKPushRegistry регистрирует приложение на получение уведомлений определённого типа — VoIP, Complication, FileProvider или PushToTalk.
  • С iOS 13 единственное разрешённое применение PushKit — индикация входящих вызовов через CallKit; фоновое обновление данных через PushKit запрещено.
  • Отличие от APNs — выделенный TCP-канал без буферизации и гарантированное пробуждение приложения из любого состояния.
  • Payload ограничен 5 КБ; каждый VoIP-push должен вызывать reportNewIncomingCall в течение 5 секунд.
  • Диагностика PushKit требует физического устройства — симулятор не поддерживается; токен необходимо обновлять при каждом запуске.
  • PushKit + CallKit — стандартная связка для VoIP-приложений: PushKit доставляет уведомление, CallKit отображает системный экран вызова.

Мы разработаем мобильное приложение под ключ

IT Sectr создаёт приложения для iOS и Android для стартапов и бизнеса с 2017 года. Мы проконсультируем вас и предложим наилучшее решение.

Обсудить проект

Читайте также