PushKit to framework Apple do dostarczania powiadomień push z gwarantowaną natychmiastową dostawą, przeznaczony przede wszystkim dla aplikacji VoIP. W przeciwieństwie do standardowych APNs (Apple Push Notification service), które mogą się opóźniać lub grupować, PushKit używa stałego połączenia TCP między urządzeniem a serwerami Apple. Według Apple Developer Documentation, 2026, PushKit zapewnia opóźnienie dostawy poniżej 500 milisekund, co jest krytyczne dla aplikacji czasu rzeczywistego — połączeń głosowych i wideo.
Najważniejsze
PushKit to framework Apple, wprowadzony w iOS 8, który zapewnia mechanizm dostarczania powiadomień push z gwarantowanym priorytetem poprzez stałe połączenie z serwerami APNs. W przeciwieństwie do zwykłych powiadomień, które przechodzą przez jeden kanał APNs i mogą się opóźniać, powiadomienia PushKit używają dedykowanego strumienia z wyższym priorytetem, co zapewnia dostawę praktycznie w czasie rzeczywistym.
Technicznie PushKit działa poprzez stałe połączenie TCP między urządzeniem a serwerami push Apple. Gdy serwer wysyła powiadomienie VoIP, połączenie natychmiast przekazuje je na urządzenie, które budzi aplikację i wywołuje delegata PKPushRegistry. Aplikacja nie musi być w aktywnym stanie — PushKit może ją obudzić z tła, stanu zakończenia, a nawet po restarcie urządzenia.
Według badań Microsoft Research (2024) dotyczących opóźnień powiadomień push na platformach mobilnych, medianowe opóźnienie powiadomień PushKit wynosi 120–350 ms, podczas gdy standardowe powiadomienia APNs wykazują medianę 1–5 sekund. Różnica o rząd wielkości wynika właśnie z dedykowanego kanału TCP i priorytetowego przetwarzania po stronie Apple.
PushKit obsługuje cztery typy: VoIP (dla połączeń), Complication (dla danych na tarcze watchOS), FileProvider (dla synchronizacji plików) i PushToTalk (dla funkcji radiotelefonu). Od iOS 13 tylko typ VoIP pozostaje szeroko dostępny dla zewnętrznych programistów. Complication i FileProvider mają wąskie zastosowanie i są ograniczone do własnych ekosystemów Apple.
| Typ PushKit | Przeznaczenie | Dostępność |
|---|---|---|
| VoIP | Indykacja połączeń głosowych i wideo | iOS 8+, App Store |
| Complication | Aktualizacja danych na tarczach Apple Watch | watchOS 6+ |
| FileProvider | Sygnał o nowych plikach w File Provider Extension | iOS 11+, ograniczony |
| PushToTalk | Funkcja radiotelefonu w aplikacjach korporacyjnych | iOS 16+, ograniczony dostęp |
APNs (Apple Push Notification service) — uniwersalna usługa dostarczania powiadomień push, działająca przez jeden kanał dla wszystkich aplikacji. Apple może buforować, grupować lub nawet odrzucać powiadomienia APNs przy przeciążeniu kanału. PushKit natomiast używa dedykowanego połączenia dla każdego typu powiadomień, a Apple gwarantuje dostarczenie każdego VoIP-push bez buforowania.
Różnica uwidacznia się w scenariuszach krytycznych czasowo: połączenie przychodzące dostarczone przez APNs może nadejść z opóźnieniem 10–30 sekund lub w ogóle nie nadejść, jeśli urządzenie jest w trybie oszczędzania energii. PushKit dostarcza to samo powiadomienie w 100–500 ms niezależnie od stanu urządzenia, ponieważ jego kanał TCP jest utrzymywany aktywny przez system w priorytetowy sposób.
| Parametr | PushKit | APNs |
|---|---|---|
| Typ połączenia | Stałe TCP (dedykowany kanał) | Wspólny kanał z buforowaniem |
| Medianowe opóźnienie | 120–350 ms | 1–5 sekund |
| Budzenie aplikacji | Zawsze, z dowolnego stanu | Tylko jeśli aplikacja nie jest zabita |
| Rozmiar payload | Do 5 KB | Do 4 KB |
| Grupowanie iOS | Nie | Tak |
Architektura PushKit jest zbudowana wokół PKPushRegistry — obiektu, który rejestruje aplikację do odbierania powiadomień określonego typu. Aplikacja tworzy instancję PKPushRegistry, określa żądany typ (np. PKPushTypeVoIP) i ustawia delegata. Po rejestracji system automatycznie utrzymuje połączenie z APNs i dostarcza powiadomienia push przez delegata.
Każde powiadomienie jest reprezentowane przez obiekt PKPushPayload, który zawiera słownik dictionaryPayload z danymi od serwera. Rozmiar payload jest ograniczony do 5 KB, co wystarcza do przekazania metadanych połączenia: identyfikatora dzwoniącego, typu połączenia (audio/wideo), nazwy kontaktu i tokena sesji. Sam strumień medialny jest przesyłany oddzielnie przez WebRTC lub inny protokół czasu rzeczywistego.
import PushKit
class PushKitManager: NSObject {
private let pushRegistry = PKPushRegistry(queue: .main)
func configure() {
pushRegistry.delegate = self
pushRegistry.desiredPushTypes = [.voIP]
}
}
PushKit wywołuje metodę delegata przy otrzymaniu powiadomienia. W tym momencie aplikacja powinna wyodrębnić dane z dictionaryPayload i natychmiast wyświetlić połączenie przez CallKit, w przeciwnym razie system może zakończyć zadanie w tle. Apple zaleca zakończenie przetwarzania w ciągu 30 sekund, ale dla połączeń VoIP krytyczne jest wyświetlenie ekranu połączenia przed upływem pierwszej sekundy.
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
)
}
}
Wraz z wydaniem iOS 13 Apple wprowadziło surowe ograniczenia dotyczące używania PushKit. Programiści masowo używali VoIP-push jako ukrytego mechanizmu do aktualizacji aplikacji w tle — budzenie przez PushKit pozwalało ładować treści, synchronizować dane i aktualizować interfejs bez jawnej zgody użytkownika. Apple uznało to za naruszenie koncepcji oszczędzania energii i ograniczyło PushKit wyłącznie do indykacji połączeń przychodzących.
Teraz każde powiadomienie PushKit musi niezwłocznie prowadzić do wyświetlenia połączenia przychodzącego przez CallKit. Jeśli system wykryje, że PushKit jest używany do innych celów — na przykład do synchronizacji w tle lub aktualizacji treści bez wyświetlania połączenia — aplikacja może zostać odrzucona podczas moderacji lub odłączona od usługi PushKit. Apple usunęło również możliwość używania PushKit do aktualizacji danych w tle od iOS 13.
Pełna integracja PushKit obejmuje rejestrację, uzyskanie tokena push i przetwarzanie przychodzących powiadomień. PushKit samodzielnie żąda zgody na wysyłanie powiadomień — dodatkowe wywołanie UNUserNotificationCenter nie jest wymagane dla samego PushKit, ale może być potrzebne dla lokalnych powiadomień aplikacji. Po rejestracji system wywołuje metodę pushRegistry:didUpdatePushCredentials do przekazania tokena push, który należy wysłać na serwer.
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)")
}
}
Strona serwerowa wysyła powiadomienie PushKit przez APNs z push-type = voip i nagłówkiem apns-push-type: voip. W przeciwieństwie do zwykłych APNs, VoIP-push używa własnego certyfikatu i nie wymaga konfiguracji topic. Payload powinien zawierać minimalne dane do identyfikacji połączenia.
// Przykład payload VoIP push
{
"aps": {
"alert": {}
},
"caller": "+15551234567",
"callerName": "Alice Johnson",
"sessionId": "abc-123-def",
"hasVideo": false
}
Debugowanie PushKit jest trudniejsze niż standardowych APNs, ponieważ PushKit nie działa na symulatorze iOS. Do diagnostyki potrzebny jest fizyczny iPhone lub iPad. Pierwszym oznaką poprawnego działania jest wywołanie pushRegistry:didUpdatePushCredentials przy uruchomieniu i pojawienie się tokena push określonego formatu (64 znaki hex dla VoIP). Jeśli delegat nie jest wywoływany, sprawdź entitlements swojej aplikacji.
Innym częstym problemem jest PushKit nie dostarcza powiadomień po aktualizacji aplikacji. Dzieje się tak, jeśli zmienił się token push, ale serwer nadal używa starego. Rozwiązaniem jest wysyłanie świeżego tokena na serwer przy uruchomieniu aplikacji i usuwanie nieaktualnych tokenów przy wywołaniu pushRegistry:didInvalidatePushTokenForType. Apple zaleca również zaimplementowanie mechanizmu fallback przez zwykłe APNs.
| Problem | Przyczyna | Rozwiązanie |
|---|---|---|
| Nie wywołuje się didUpdatePushCredentials | Brak entitlements lub nieprawidłowy typ | Sprawdź Capabilities → Push Notifications + VoIP w Xcode |
| Push przychodzi z opóźnieniem | Urządzenie w trybie Low Power Mode lub słaby sygnał | PushKit nie może ominąć ograniczeń sprzętowych |
| Nie przychodzą powiadomienia po restarcie | Zmiana tokena push po ponownej instalacji aplikacji | Poproś o nowy token i zaktualizuj go na serwerze |
| App Store odrzucił z powodu PushKit | PushKit używany nie do połączeń | Upewnij się, że każdy push prowadzi do reportNewIncomingCall |
Często zadawane pytania
Technicznie tak, ale bez sensu. Od iOS 13 jedynym dozwolonym zastosowaniem PushKit jest indykacja połączeń przychodzących, która wymaga CallKit do wyświetlenia. Używanie PushKit bez CallKit doprowadzi do odrzucenia aplikacji w App Store.
Maksymalny rozmiar payload dla PushKit wynosi 5 KB (5120 bajtów). To o 1 KB więcej niż w zwykłych powiadomieniach APNs, co pozwala przesłać więcej metadanych o połączeniu.
Apple automatycznie unieważnia token push przy usunięciu aplikacji. Serwer otrzyma powiadomienie o unieważnieniu i powinien zaprzestać wysyłania push na ten token. Próba wysłania push na nieważny token spowoduje błąd APNs 410.
PushKit jest dostępny na macOS 10.14+ dla aplikacji Mac stworzonych przy użyciu Mac Catalyst lub AppKit. Funkcjonalność jest w pełni analogiczna do wersji iOS, w tym obsługa powiadomień VoIP.
Użyj własnej analityki: śledź czas między wysłaniem push z serwera a wywołaniem didReceiveIncomingPushWithPayload na kliencie. Średni czas poniżej 500 ms wskazuje na poprawną pracę PushKit.
Podsumowanie
Opracujemy aplikację mobilną pod klucz
IT Sectr tworzy aplikacje na iOS i Androida dla startupów i firm od 2017 roku. Doradzimy Ci i zaproponujemy najlepsze rozwiązanie.
Przeczytaj również