Inconsistent VoIP Push Behavior Post Network Restoration

We are observing unexpected behavior in Apple Push Notification Service (APNS) delivery and would appreciate clarification and guidance. Below is a detailed breakdown of the scenario and related questions.

Abbreviations:

  • APNP – Apple Push Notification Provider
  • APNS – Apple Push Notification Service

Scenario:

  • User1 is registered on iOS device1.
  • Flight Mode is enabled on iOS device1.
  • User2 initiates a call to User1 (Time t = 0 sec).
  • User2 cancels the outgoing call after 5 seconds (Time t = 5 sec).
  • Flight Mode is disabled on iOS device1 after 20 seconds (Time t = 25 sec).

Observation:

  • iOS device1 displays an incoming call notification (CallKit UI) after flight mode is turned off, despite the call being cancelled by User2.
  • This notification disappears automatically after approximately 8–10 seconds.

Logic Flow:

  • At time t = 0, our APNP sends a VoIP push (priority) to APNS for the incoming call.
  • Since device1 is in flight mode, APNS cannot deliver the push.
  • At t = 25 sec, after flight mode is turned off, APNS delivers the cached VoIP push to device1.
  • The app takes ~5 seconds to initialize (CSDK setup, SIP registration, etc.).
  • It eventually receives a SIP NOTIFY with state="full" and empty dialog info (indicating no active call).
  • Consequently, the CallKit incoming call is removed after ~8 seconds.

Questions:

→ We set the apns-expiration header to 0, expecting that the VoIP push would not be delivered if the device was unreachable when the push was sent. However, APNS still delivers the push 20–30 seconds later, once the device is back online.

Q. Why is the apns-expiration header not respected in this case?

→ Upon receiving the VoIP push, we require ~10–12 seconds to determine if a visible CallKit notification is still relevant (e.g., by completing SIP registration and checking for active dialogs).

Q. Is it acceptable, per Apple guidelines, to intentionally delay showing the CallKit UI (incoming call) for 10–15 seconds after receiving the VoIP push?

→ Apple documentation states that the priority VoIP push channel should be used only for notifying incoming calls, while regular (non-VoIP) pushes should be used for other updates, including call cancellations.

Q. What is the rationale behind discouraging the use of the priority VoIP push channel for call cancellation events? In some cases, immediate cancellation notification is as critical as the initial incoming call. Would Apple consider it acceptable to occasionally use the priority VoIP channel for rare call-cancellation scenarios without risking throttling or suspension?

→ In our implementation, we send an incoming call notification via the priority VoIP channel. Shortly after, we send a call cancellation notification on the regular push channel, marked with "content-available": 1. We expect this regular push to wake the app (triggering application:didReceiveRemoteNotification:fetchCompletionHandler:), but in practice the app never wakes, and our debug logs inside that delegate method never appear.

Q. Under what exact conditions does a "content-available": 1 regular push fail to wake the app when it follows a VoIP push? Are there additional requirements (e.g., background modes, rate limits, power optimizations) that could prevent the delegate from being called?

→ According to Apple documentation: “APNs stores only one notification per bundle ID. When multiple notifications are sent to the same device for the same bundle ID, APNs keeps only the latest one.” However, in our tests: If a device is offline when APNs receives both: (a) a priority VoIP push for an incoming call, (b) a regular push for call cancellation (same bundle ID), Upon the device reconnecting, APNs still delivers the earlier VoIP push, instead of discarding it and delivering only the most recent (cancellation) notification.

Q. Why doesn’t APNs replace the queued VoIP push with the newer regular push when both share the same bundle ID? Is this expected behavior due to channel type differences (VoIP vs. regular), or is there a way to ensure that the latest notification (even if regular) supersedes the earlier VoIP push?

We’d appreciate your input or recommendations on handling such delayed pushes and any best practices for VoIP push expiration handling and call UI timing.

Inconsistent VoIP Push Behavior Post Network Restoration
 
 
Q