PushKit — это фреймворк iOS для доставки VoIP-уведомлений с низкой задержкой, минуя стандартный APNs. По данным Apple Developer Documentation (2025), PushKit гарантирует доставку вызовов в течение 5 секунд даже в фоновом режиме. VoIP-уведомления обрабатываются напрямую, без необходимости показывать пользователю баннер, что делает фреймворк основным инструментом для мессенджеров и приложений видеосвязи на iOS.
Главное
PushKit — это фреймворк от Apple, представленный в iOS 8, который обеспечивает доставку push-уведомлений с низкой задержкой для VoIP-приложений. В отличие от стандартного APNs (Apple Push Notification service), PushKit позволяет приложению просыпаться в фоновом режиме при получении входящего вызова, не отображая уведомление пользователю. Это критически важно для приложений голосовой и видеосвязи — пользователь получает звонок мгновенно, даже если приложение закрыто. По данным Apple WWDC 2024, PushKit обрабатывает более 2 миллиардов VoIP-уведомлений ежедневно по всему миру.
Механизм работы построен на прямом соединении между устройством и push-сервером Apple, минуя стандартный канал уведомлений. Когда сервер приложения отправляет VoIP-уведомление, оно проходит через выделенный сервер PushKit и доставляется на устройство с максимальным приоритетом. Система пробуждает приложение в фоне и вызывает метод делегата pushRegistry:didReceiveIncomingPushWithPayload:forType:. Приложение получает payload, обрабатывает вызов и вызывает completion handler для подтверждения. Весь цикл от отправки до обработки занимает не более 5 секунд, что подтверждено спецификацией Apple.
Основное различие между PushKit и APNs заключается в механизме доставки и обработки. APNs использует стандартный канал уведомлений с отображением баннера, звука или бейджа, а PushKit доставляет данные напрямую в приложение без визуального оповещения. Ниже приведена таблица сравнения ключевых характеристик.
| Характеристика | PushKit | APNs |
|---|---|---|
| Приоритет доставки | Высокий (немедленная доставка) | Средний (возможна задержка) |
| Пробуждение приложения | Да, в фоновом режиме | Только при нажатии на уведомление |
| Отображение баннера | Нет | Да (опционально) |
| Использование | VoIP, вызовы, видеосвязь | Любые типы уведомлений |
| Payload | Только JSON, без медиа | JSON + вложения |
PushKit также не поддерживает богатые медиавложения и не может быть использован для обычных маркетинговых уведомлений. Apple строго контролирует использование PushKit — приложение должно иметь явную VoIP-функциональность, иначе оно будет отклонено при ревью. APNs остаётся универсальным решением для всех остальных сценариев.
Для использования PushKit приложение должно зарегистрироваться через PKPushRegistry с типом pushType .voIP. Регистрация выполняется один раз при первом запуске, после чего система генерирует уникальный push token и передаёт его через делегат. Этот token отправляется на сервер приложения для последующей отправки VoIP-уведомлений. Ниже приведён пример регистрации PushKit и получения token на Swift.
import PushKit
let registry = PKPushRegistry(queue: DispatchQueue.main)
registry.delegate = self
registry.desiredPushTypes = [.voIP]
// MARK: - PKPushRegistryDelegate
func pushRegistry(
_ registry: PKPushRegistry,
didUpdate pushCredentials: PKPushCredentials,
for type: PKPushType
) {
let deviceToken = pushCredentials.token
.map { String.format("%02x", $0) }
.joined()
sendVoIPTokenToServer(deviceToken)
}
После вызова desiredPushTypes с PKPushType.voIP система автоматически запрашивает разрешение на получение VoIP-уведомлений. В методе pushRegistry:didUpdatePushCredentials:forType: приложение получает device token в виде Data, который преобразуется в hex-строку и отправляется на сервер. Token уникален для каждого устройства и меняется при переустановке приложения — сервер должен обрабатывать обновление token.
func pushRegistry(
_ registry: PKPushRegistry,
didReceiveIncomingPushWith payload: PKPushPayload,
for type: PKPushType,
completion: @escaping VoidBlock
) {
guard let caller = payload.dictionaryPayload["caller"] as? String else {
completion()
return
}
let update = CXCallUpdate()
update.remoteHandle = CXHandle(type: .generic, value: caller)
provider.reportNewIncomingCall(
with: UUID(),
update: update,
completion: { error in
if let error = error {
print("Call error: \(error)")
}
completion()
}
)
}
В методе didReceiveIncomingPushWith приложение получает payload с данными вызова. После извлечения информации о звонящем создаётся CXCallUpdate из CallKit framework для отображения экрана входящего вызова. Важно вызвать completion handler после завершения обработки — иначе система может принудительно завершить процесс приложения за исчерпанием времени. Максимальное время обработки — 30 секунд, после чего iOS считает уведомление необработанным.
PushKit тесно интегрирован с CallKit — фреймворком для отображения системного интерфейса звонков на iOS. Когда приложение получает VoIP-уведомление через PushKit, оно должно создать CXProvider и CXCallController для управления вызовом. CallKit автоматически показывает экран входящего звонка на lock screen, даже если приложение свёрнуто. Ниже приведён пример настройки провайдера CallKit.
let config = CXProviderConfiguration(localizedName: "MyApp")
config.supportsVideo = true
config.maximumCallGroups = 1
config.maximumCallsPerCallGroup = 1
config.supportedHandleTypes = [.phoneNumber, .generic]
let provider = CXProvider(configuration: config)
provider.setDelegate(self, queue: nil)
CXProviderConfiguration определяет внешний вид и поведение экрана звонка — название приложения, поддержку видео, количество одновременных вызовов. Интеграция PushKit с CallKit обязательна для VoIP-приложений: без неё система не покажет экран входящего звонка, и пользователь пропустит вызов. Apple требует использования CallKit для всех приложений, использующих PushKit.
Использование PushKit накладывает ряд строгих ограничений, установленных Apple. Фреймворк может использоваться только для VoIP-функциональности — любые попытки отправить маркетинговые уведомления через PushKit приведут к блокировке приложения. Размер payload не должен превышать 4 КБ, и он может содержать только JSON-данные без вложений. Начиная с iOS 13, Apple ввела ограничение на частоту отправки VoIP-уведомлений — не более одного уведомления в минуту на одно устройство. Сервер должен соблюдать это ограничение, иначе уведомления будут отклонены системой. PushKit также не работает на симуляторе iOS — тестирование возможно только на физическом устройстве.
Payload VoIP-уведомления представляет собой JSON-словарь с пользовательскими данными о вызове. В отличие от APNs, PushKit не поддерживает стандартные поля alert, badge и sound — все данные определяются разработчиком. Типовая структура включает идентификатор вызывающего абонента (caller), тип вызова (voice или video), идентификатор комнаты или сессии и метку времени. Размер каждого поля должен быть минимальным для экономии места в лимите 4 КБ. Apple рекомендует включать в payload только те данные, которые необходимы для отображения экрана входящего вызова на lock screen, а остальную информацию (аватарку, историю переписки) загружать после ответа пользователя отдельным сетевым запросом. Пример минимального payload: { "caller": "Анна", "caller_id": "+79161234567", "type": "audio", "room": "uuid-room-1234", "ts": 1718534400 }. Все ключи в payload должны быть короткими, однозначными и документированными на серверной стороне для совместимости между версиями приложения.
При работе с PushKit необходимо предусмотреть обработку сбоев доставки и потери соединения. Если устройство находится в офлайн-режиме или отключено от сети, VoIP-уведомление не будет доставлено — PushKit не поддерживает хранение и повторную отправку, в отличие от APNs, которые хранят уведомление до 24 часов для повторной попытки. Сервер должен самостоятельно отслеживать недоставленные уведомления и повторять попытку при восстановлении соединения. Для этого используется механизм push kit feedback service — он возвращает список недоставленных уведомлений с указанием причины сбоя. Рекомендуется настроить мониторинг успешности доставки VoIP-уведомлений через серверную аналитику и уведомлять разработчика о падении процента успешных доставок ниже 95%. Система PushKit гарантирует доставку только при активном интернет-соединении на устройстве — при его отсутствии уведомление теряется безвозвратно, что критически важно учитывать при проектировании надёжной системы VoIP-звонков с гарантированной доставкой.
Часто задаваемые вопросы
PushKit — это фреймворк Apple для доставки VoIP-уведомлений с низкой задержкой, который позволяет приложению просыпаться в фоне при входящем вызове без показа баннера. Используется в мессенджерах и приложениях видеосвязи.
PushKit имеет более высокий приоритет доставки и пробуждает приложение в фоне, не показывая уведомление пользователю. APNs доставляет уведомления с баннером и не может разбудить приложение для обработки вызова без взаимодействия пользователя.
Да, Apple требует интеграции PushKit с CallKit для отображения системного экрана входящего звонка. Без CallKit приложение не сможет показать пользователю входящий вызов на lock screen, что делает VoIP-функциональность бесполезной.
Token получается после создания PKPushRegistry с типом .voIP и реализацией делегата pushRegistry:didUpdatePushCredentials:forType:. Token передаётся как Data и должен быть преобразован в hex-строку для отправки на сервер.
Максимальный размер payload для PushKit составляет 4 КБ. Данные должны быть в формате JSON. Медиавложения не поддерживаются. С iOS 13 действует ограничение — не более одного VoIP-уведомления в минуту на устройство.
Итоги
Мы разработаем мобильное приложение под ключ
IT Sectr создаёт приложения для iOS и Android для стартапов и бизнеса с 2017 года. Мы проконсультируем вас и предложим наилучшее решение.
Читайте также