PushKit е рамка на Apple за доставяне на push известия с гарантирано незабавно доставяне, предназначена преди всичко за VoIP приложения. За разлика от стандартните APNs (Apple Push Notification service), които могат да се забавят или да се групират, PushKit използва постоянна TCP връзка между устройството и сървърите на Apple. Според Apple Developer Documentation, 2026, PushKit осигурява забавяне на доставяне по-малко от 500 милисекунди, което е критично за приложенията в реално време — гласови и видео обаждания.
Основни поенти
PushKit е рамка на Apple, въведена в iOS 8, която предоставя механизъм за доставяне на push известия с гарантиран приоритет чрез постоянна връзка с APNs сървъри. За разлика от обикновените известия, които преминават през единен APNs канал и могат да се забавят, PushKit известията използват поток с по-висок приоритет, осигурявайки доставяне практически в реално време.
Технически, PushKit работи чрез постоянна TCP връзка между устройството и push сървърите на Apple. Когато сървърът изпраща VoIP известие, връзката го пренася незабавно на устройството, което събужда приложението и извиква PKPushRegistry делегата. Приложението няма нужда да е в активно състояние — PushKit може да го събуди от фона, прекратено състояние или дори след рестартиране на устройството.
Според проучване на Microsoft Research (2024) относно забавянията на push известия на мобилни платформи, медианното забавяне на PushKit известията е 120–350 ms, докато стандартните APNs известия показват медиана от 1–5 секунди. Разликата в размер на промена се обяснява именно с посветения TCP канал и приоритетната обработка от страна на Apple.
PushKit поддържа четири типа: VoIP (за обаждания), Complication (за данни на циферблатите на watchOS), FileProvider (за синхронизация на файлове) и PushToTalk (за функция на радиоция). От iOS 13 насамо, само VoIP типът остава широко достъпен за внешни разработчици. Complication и FileProvider имат тясно специализирано приложение и са ограничени до собствените екосистеми на Apple.
| PushKit тип | Предназначение | Достъпност |
|---|---|---|
| VoIP | Индикация на входящи гласови и видео обаждания | iOS 8+, App Store |
| Complication | Актуализиране на данни на циферблатите на Apple Watch | watchOS 6+ |
| FileProvider | Сигнал за нови файлове в File Provider Extension | iOS 11+, ограничено |
| PushToTalk | Функция на радиоция в корпоративни приложения | iOS 16+, ограничен достъп |
APNs (Apple Push Notification service) — универсална услуга за доставяне на push известия, работеща чрез единен канал за всички приложения. Apple може да буферира, групира или дори да изхвърля APNs известия при претоварване на канала. PushKit, от друга страна, използва посветена връзка за всеки тип известие, и Apple гарантира доставянето на всеки VoIP-push без буфериране.
Разликата се проявява в сценариите, критични към времето: входящо обаждане, доставено чрез APNs, може да дойде с забавяне от 10–30 секунди или изобщо да не дойде, ако устройството е в режим на икономия на енергия. PushKit доставя същото известие за 100–500 ms, независимо от състоянието на устройството, тъй като неговият TCP канал се поддържа активен от системата по приоритетен начин.
| Параметър | PushKit | APNs |
|---|---|---|
| Тип връзка | Постоянна TCP (посветен канал) | Общ канал с буфериране |
| Медианно забавяне | 120–350 ms | 1–5 секунди |
| Събуждане на приложението | Винаги, от всяко състояние | Само ако приложението не е прекратено |
| Размер на payload | До 5 KB | До 4 KB |
| iOS групиране | Не | Да |
Архитектурата на PushKit е изградена около PKPushRegistry — обект, който регистрира приложението за получаване на известия от определен тип. Приложението създава инстанция на PKPushRegistry, посочва желания тип (напр. PKPushTypeVoIP) и назначава делегат. След регистрация, системата автоматично поддържа връзката с APNs и доставя push известията чрез делегата.
Всяко известие се представя от обект PKPushPayload, който съдържа речник dictionaryPayload с данни от сървъра. Размерът на payload е ограничен до 5 KB, което е достатъчно за пренасяне на метаданни на обаждането: идентификатор на обаждащия, тип на обаждането (аудио/видео), име на контакта и токен на сесията. Медийният поток се пренася отделно чрез WebRTC или друг реален протокол.
import PushKit
class PushKitManager: NSObject {
private let pushRegistry = PKPushRegistry(queue: .main)
func configure() {
pushRegistry.delegate = self
pushRegistry.desiredPushTypes = [.voIP]
}
}
PushKit извиква делегатския метод при получаване на известие. В този момент, приложението трябва да извлече данните от dictionaryPayload и незабавно да покаже обаждането чрез CallKit, в противен случай системата може да приключи фоновата задача. Apple препоръчва да завършите обработката в рамките на 30 секунди, но за VoIP обаждания е критично да покажете екрана на обаждането преди изтичането на първата секунда.
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, Apple въведе строги ограничения за използването на PushKit. Разработчиците масово използваха VoIP-push като скрит механизъм за фоново актуализиране на приложенията — събуждането чрез PushKit позволяваше зареждане на съдържание, синхронизация на данни и актуализиране на интерфейса без изрично разрешение от потребитела. Apple смята това за нарушение на концепцията за икономия на енергия и ограничи PushKit само до индикация на входящи обаждания.
Сега всяко PushKit известие трябва незабавно да доведе до показване на входящо обаждане чрез CallKit. Ако системата открие, че PushKit се използва за други цели — например, за фонова синхронизация или актуализиране на съдържание без показване на обаждане — приложението може да бъде отхвърлено при модерация или да бъде прекратена връзката му с PushKit услугата. Apple също така премахна възможността за използване на PushKit за фоново актуализиране на данни от iOS 13 насамо.
Пълната интеграция на PushKit включва регистрация, получаване на push token и обработка на входящи известия. PushKit независимо изисква разрешение за изпращане на известия — допълнително извикване на UNUserNotificationCenter не е нужно за самия PushKit, но може да е необходимо за локалните известия на приложението. След регистрация, системата извиква метода pushRegistry:didUpdatePushCredentials за пренасяне на push token, който трябва да бъде изпратен на сървъра.
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)")
}
}
Сървърната страна изпраща PushKit известието чрез APNs с push-type = voip и заглавие apns-push-type: voip. За разлика от обикновените APNs, VoIP-push използва собствен сертификат и не изисква конфигурация на topic. Payload трябва да съдържа минимални данни за идентификация на обаждането.
// Пример за VoIP push payload
{
"aps": {
"alert": {}
},
"caller": "+15551234567",
"callerName": "Alice Johnson",
"sessionId": "abc-123-def",
"hasVideo": false
}
Отладването на PushKit е по-трудно от стандартните APNs, тъй като PushKit не работи на iOS симулатора. За диагностика е необходимо физическо iPhone или iPad. Първият признак за правилна работа е извикването на pushRegistry:didUpdatePushCredentials при стартиране и появата на push token с определен формат (64 hex символа за VoIP). Ако делегатът не се извиква, проверете entitlements на приложението си.
Друг чест проблем е, че PushKit не доставя известия след актуализиране на приложението. Това се случва, ако push token се промени, но сървърът продължава да използва стария. Решението е да изпратите нов token на сървъра при стартиране на приложението и да премахнете невалидните tokenове при извикване на pushRegistry:didInvalidatePushTokenForType. Apple също препоръчва да приложите fallback механизъм чрез обикновени APNs.
| Проблем | Причина | Решение |
|---|---|---|
| didUpdatePushCredentials не се извиква | Липсващи entitlements или грешен тип | Проверете Capabilities → Push Notifications + VoIP в Xcode |
| Push идва с забавяне | Устройството е в Low Power Mode или слаб сигнал | PushKit не може да заобиколи хардуерните ограничения |
| Известията не идват след рестарт | Промяна на push token след преинсталиране на приложението | Изискайте нов token и го актуализирайте на сървъра |
| App Store отхвърлено заради PushKit | PushKit не се използва за обаждания | Убедете се, че всяко push води до reportNewIncomingCall |
Често задавани въпроси
Технически да, но е безсмислено. От iOS 13 насамо, единственото разрешено приложение на PushKit е индикация на входящи обаждания, което изисква CallKit за показване. Използването на PushKit без CallKit ще доведе до отхвърляне на приложението в App Store.
Максималният размер на payload за PushKit е 5 KB (5120 байта). Това е 1 KB повече от обикновените APNs известия, което позволява пренасянето на повече метаданни за обаждането.
Apple автоматично анулира push token при премахване на приложението. Сървърът ще получи уведомление за анулиране и трябва да спре да изпраща push на този token. Опитът за изпращане на push към невалиден token ще причини APNs грешка 410.
PushKit е достъпен на macOS 10.14+ за Mac приложения, създадени с Mac Catalyst или AppKit. Функционалността е напълно аналогична на iOS версията, включително поддръжка на VoIP известия.
Използвайте собствен анализ: проследете времето между изпращането на push от сървъра и извикването на didReceiveIncomingPushWithPayload на клиента. Средно време под 500 ms посочва правилна работа на PushKit.
Заключение
Ще разработим мобилно приложение под ключ
IT Sectr създава iOS и Android приложения за стартъпи и бизнеси от 2017 г. Ще ви консултираме и ще предложим най-доброто решение.
Прочетете също