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 для відображення екрана вхідного виклику. Важливо викликати 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 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.
Читайте також