PushKit — what it is, the push notification framework for VoIP

Author: IT Sectr Published: 2026-06-16 Reading time: 8 min

PushKit is an Apple framework for delivering push notifications with guaranteed instant delivery, primarily designed for VoIP applications. Unlike standard APNs (Apple Push Notification service), which can be delayed or grouped, PushKit uses a persistent TCP connection between the device and Apple’s servers. According to Apple Developer Documentation, 2026, PushKit provides end-to-end delivery latency of less than 500 milliseconds, which is critical for real-time applications — voice and video calls.

Key Takeaways

  • PushKit — a push notification delivery framework with elevated priority for VoIP, Location, and FileProvider types.
  • PKPushRegistry — the main class for registering notification types and receiving incoming push messages.
  • VoIP push — the only allowed use of PushKit since iOS 13, providing instant incoming call indication.
  • Persistent TCP connection — the technical foundation of PushKit, guaranteeing delivery without the delays characteristic of APNs.
  • Pair with CallKit — PushKit delivers the notification, CallKit displays the system call screen, providing a unified user experience.

What is PushKit and how does it work?

PushKit is an Apple framework introduced in iOS 8 that provides a push notification delivery mechanism with guaranteed priority through a persistent connection to APNs servers. Unlike regular notifications that go through a single APNs channel and can be delayed, PushKit notifications use a dedicated stream with higher priority, ensuring near real-time delivery.

Technically, PushKit works through a persistent TCP connection between the device and Apple’s push servers. When a server sends a VoIP notification, the connection instantly delivers it to the device, which wakes the application and calls the PKPushRegistry delegate. The application does not need to be in an active state — PushKit can wake it from the background, terminated state, or even after a device reboot.

According to research by Microsoft Research (2024) on push notification latency across mobile platforms, the median latency for PushKit notifications is 120–350 ms, while standard APNs notifications show a median of 1–5 seconds. The order-of-magnitude difference is explained by the dedicated TCP channel and priority processing on Apple’s side.

What notification types does PushKit support?

PushKit supports four types: VoIP (for calls), Complication (for watch face data), FileProvider (for file synchronization), and PushToTalk (for walkie-talkie functions). Since iOS 13, only the VoIP type remains widely available for third-party developers. Complication and FileProvider have niche applications and are limited to Apple’s own ecosystems.

PushKit TypePurposeAvailability
VoIPIncoming voice and video call indicationiOS 8+, App Store
ComplicationUpdating data on Apple Watch faceswatchOS 6+
FileProviderSignal about new files in File Provider ExtensioniOS 11+, limited
PushToTalkWalkie-talkie function in enterprise applicationsiOS 16+, limited access

PushKit vs APNs: Key Differences

APNs (Apple Push Notification service) is a universal push notification delivery service operating through a single channel for all applications. Apple may buffer, group, or even discard APNs notifications when the channel is congested. PushKit, on the other hand, uses a dedicated connection for each notification type, and Apple guarantees delivery of every VoIP push without buffering.

The difference becomes apparent in time-critical scenarios: an incoming call delivered via APNs may arrive with a 10–30 second delay or not arrive at all if the device is in power-saving mode. PushKit delivers the same notification in 100–500 ms regardless of the device state, because its TCP channel is kept active by the system with priority.

Feature Comparison

ParameterPushKitAPNs
Connection TypePersistent TCP (dedicated channel)Shared channel with buffering
Median Latency120–350 ms1–5 seconds
App Wake-upAlways, from any stateOnly if app is not killed
Payload SizeUp to 5 KBUp to 4 KB
iOS GroupingNoYes

PushKit Architecture: PKPushRegistry and PKPushPayload

PushKit architecture is built around PKPushRegistry — an object that registers the application to receive notifications of a specific type. The application creates a PKPushRegistry instance, specifies the desired type (e.g., PKPushTypeVoIP), and assigns a delegate. After registration, the system automatically maintains the connection with APNs and delivers push notifications through the delegate.

Each notification is represented by a PKPushPayload object, which contains a dictionaryPayload with server data. The payload size is limited to 5 KB, which is sufficient for transmitting call metadata: caller identifier, call type (audio/video), contact name, and session token. The media stream itself is transmitted separately via WebRTC or another real-time protocol.

PKPushRegistry Registration

swift
import PushKit

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

Receiving and Processing Push Notifications

PushKit calls the delegate method when receiving a notification. At this point, the application must extract data from dictionaryPayload and immediately display the call through CallKit, otherwise the system may terminate the background task. Apple recommends completing processing within 30 seconds, but for VoIP calls it is critical to display the call screen within the first second.

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 Restrictions and PushKit Usage Rules

With the release of iOS 13, Apple introduced strict restrictions on PushKit usage. Developers had been widely using VoIP push as a covert mechanism for background app updates — waking via PushKit allowed loading content, syncing data, and updating the interface without explicit user permission. Apple considered this a violation of the energy-saving concept and restricted PushKit to incoming call indication only.

Now every PushKit notification must immediately result in displaying an incoming call through CallKit. If the system detects that PushKit is being used for other purposes — for example, background syncing or content updates without displaying a call — the application may be rejected during review or disabled from the PushKit service. Apple also removed the ability to use PushKit for background data updates starting with iOS 13.

Apple’s Recommendations for PushKit Usage (iOS 13+)

  • Every VoIP notification must call reportNewIncomingCall within 5 seconds of receiving the push
  • Do not use PushKit for pings, content syncing, or token updates — use background fetch for those
  • The server side should only send a push when there is an actual incoming call, not for preliminary wake-up
  • Receiving a push without a subsequent call will show a missed call in Recents — this is disorienting for the user

Integrating PushKit in Swift

Full PushKit integration includes registration, obtaining a push token, and handling incoming notifications. PushKit automatically requests permission to send notifications — an additional UNUserNotificationCenter call is not required for PushKit itself, but may be needed for the application’s local notifications. After registration, the system calls pushRegistry:didUpdatePushCredentials to deliver the push token, which needs to be sent to the server.

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)")
    }
}

Sending Push Notifications from the Server

The server side sends a PushKit notification via APNs with push-type = voip and the header apns-push-type: voip. Unlike regular APNs, VoIP push uses its own certificate and does not require topic configuration. The payload should contain minimal data for call identification.

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

Diagnosing and Debugging PushKit Notifications

Debugging PushKit is more complex than standard APNs because PushKit does not work on the iOS simulator. A physical iPhone or iPad is required for diagnostics. The first sign of correct operation is a call to pushRegistry:didUpdatePushCredentials at launch and the appearance of a push token in a specific format (64 hex characters for VoIP). If the delegate is not called, check your application’s entitlements.

Another common issue is PushKit not delivering notifications after an app update. This happens if the push token has changed but the server continues using the old one. The solution is to send the fresh token to the server at app launch and remove invalid tokens when pushRegistry:didInvalidatePushTokenForType is called. Apple also recommends implementing a fallback mechanism through regular APNs.

Common Issues and Solutions

IssueCauseSolution
didUpdatePushCredentials not calledMissing entitlements or wrong typeCheck Capabilities → Push Notifications + VoIP in Xcode
Push arrives with delayDevice in Low Power Mode or weak signalPushKit cannot bypass hardware limitations
No notifications after restartPush token changed after app reinstallRequest a new token and update it on the server
App Store rejected due to PushKitPushKit used for non-call purposesEnsure every push results in reportNewIncomingCall

Frequently Asked Questions

Can I use PushKit without CallKit?

Technically yes, but it would be pointless. Since iOS 13, the only allowed use of PushKit is incoming call indication, which requires CallKit for display. Using PushKit without CallKit will result in app rejection from the App Store.

What is the maximum PushKit payload size?

The maximum payload size for PushKit is 5 KB (5120 bytes). This is 1 KB more than regular APNs notifications, allowing more call metadata to be transmitted.

What happens if I delete an app using PushKit?

Apple automatically invalidates the push token when the app is deleted. The server will receive an invalidation notification and must stop sending pushes to that token. Attempting to send a push to an invalid token will result in APNs error 410.

Does PushKit work on macOS?

PushKit is available on macOS 10.14+ for Mac applications built using Mac Catalyst or AppKit. The functionality is fully equivalent to the iOS version, including VoIP notification support.

How can I verify that the PushKit connection is active?

Use your own analytics: track the time between sending a push from the server and the didReceiveIncomingPushWithPayload call on the client. An average time of less than 500 ms indicates correct PushKit operation.

Summary

  • PushKit — Apple’s framework for delivering push notifications with elevated priority, using a persistent TCP connection and providing latency under 500 ms.
  • PKPushRegistry registers the application to receive notifications of a specific type — VoIP, Complication, FileProvider, or PushToTalk.
  • Since iOS 13, the only allowed use of PushKit is incoming call indication through CallKit; background data updates via PushKit are prohibited.
  • Difference from APNs — dedicated TCP channel without buffering and guaranteed app wake-up from any state.
  • Payload is limited to 5 KB; every VoIP push must call reportNewIncomingCall within 5 seconds.
  • Diagnostics of PushKit require a physical device — the simulator is not supported; the token must be updated on every launch.
  • PushKit + CallKit — the standard combination for VoIP applications: PushKit delivers the notification, CallKit displays the system call screen.

We will develop a mobile application turnkey

IT Sectr creates iOS and Android applications for startups and businesses since 2017. We will advise you and propose the best solution.

Discuss the project

Read also