Is there a way for a device to detect when VoIP Push has been blocked?

Hello,

I am developing an application using VoIP Push and CallKit. I have a question: Starting with iOS 13, I understand that under the VoIP Push policy, if reportNewIncomingCall is not called continuously, the VoIP Push may be blocked. Is there a way to determine if the device has been blocked?

I am curious whether PKPushRegistry itself is unable to receive pushes or if reportNewIncomingCall returns an error when it is blocked. If push notifications are not being received, what should I do to resume receiving them?

Thank you.

Answered by DTS Engineer in 813135022

I am developing an application using VoIP Push and CallKit. I have a question: Starting with iOS 13, I understand that under the VoIP Push policy, if reportNewIncomingCall is not called continuously, the VoIP Push may be blocked.

More specifically, you're required to call "reportNewIncomingCall" unless:

  1. Your app is the foreground.

  2. Your app already has an active call.

As a side note on the second case, the correct way to do this is to call "reportNewIncomingCall" and (intentionally) pass in the UUID of your existing call. This will ensure your call report either fails (with an existing call error, which you can ignore) or starts a new call (which you'll need to end on your own). This approach allows you to safely avoid race conditions where your app is attempting to report a new call at the same time the system is ending your existing call.

Is there a way to determine if the device has been blocked?

Not programmatically. Initial failures will generate crash logs when your app crashes (inside PKPushRegistry) but callservicesd will eventually stop reporting pushes entirely. It logs that this is occurring to the console, but it's not something your app could determine.

I am curious whether PKPushRegistry itself is unable to receive pushes or if reportNewIncomingCall returns an error when it is blocked.

Initially, PKPushRegistry detects that your app has returned from didReceiveIncomingPushWithPayload and crashes your app "directly"*, with a crash log that clearly shows why your app has crashed. However, after a fixed number of failures (5?), callservicesd stops all background push delivery.

*At at technical level, this does mean that it's possible for an app to bypass this crash by hacking/modifying PKPushRegistry. However, doing so just means that your app will be terminated by callservicesd a few seconds later with the Termination Reason-> 0xbaadca11.

If you're seeing 0xbaadca11, then the problem is typically that you've failed to properly initialize your PKPushRegistry at startup, preventing your app from receiving the push the system launched it to deliver.

If push notifications are not being received,

Just to clarify, the pushes themselves are actually still reaching the device as normal. What changes here is how the system delivers them them to your app.

what should I do to resume receiving them?

The simplest way is to delete and reinstall the app. I believe callservicesd does reset this every ~24 hours, but that's not all that useful for an issue that should ONLY be occurring in a development app.

__
Kevin Elliott
DTS Engineer, CoreOS/Hardware

It is not the device that gets blocked. It is your app. If you do not reportIncomingCall your app will be terminated. If you fail to do that continually, then the VoIP notifications to your app will stop being delivered to it altogether for a period of time.

In any case, it is not the device that is "blocked", but your app. If you encounter this during development and want to expedite the waiting period, you can delete your app, and install a fresh copy.

As this would be a huge inconvenience to your users if it happens in production, and there is no way for your app to know it is in the penalty box, the best way to solve this problem is to avoid running into it in the first place and always reportIncomingCalls


Argun Tekant /  DTS Engineer / Core Technologies

Accepted Answer

I am developing an application using VoIP Push and CallKit. I have a question: Starting with iOS 13, I understand that under the VoIP Push policy, if reportNewIncomingCall is not called continuously, the VoIP Push may be blocked.

More specifically, you're required to call "reportNewIncomingCall" unless:

  1. Your app is the foreground.

  2. Your app already has an active call.

As a side note on the second case, the correct way to do this is to call "reportNewIncomingCall" and (intentionally) pass in the UUID of your existing call. This will ensure your call report either fails (with an existing call error, which you can ignore) or starts a new call (which you'll need to end on your own). This approach allows you to safely avoid race conditions where your app is attempting to report a new call at the same time the system is ending your existing call.

Is there a way to determine if the device has been blocked?

Not programmatically. Initial failures will generate crash logs when your app crashes (inside PKPushRegistry) but callservicesd will eventually stop reporting pushes entirely. It logs that this is occurring to the console, but it's not something your app could determine.

I am curious whether PKPushRegistry itself is unable to receive pushes or if reportNewIncomingCall returns an error when it is blocked.

Initially, PKPushRegistry detects that your app has returned from didReceiveIncomingPushWithPayload and crashes your app "directly"*, with a crash log that clearly shows why your app has crashed. However, after a fixed number of failures (5?), callservicesd stops all background push delivery.

*At at technical level, this does mean that it's possible for an app to bypass this crash by hacking/modifying PKPushRegistry. However, doing so just means that your app will be terminated by callservicesd a few seconds later with the Termination Reason-> 0xbaadca11.

If you're seeing 0xbaadca11, then the problem is typically that you've failed to properly initialize your PKPushRegistry at startup, preventing your app from receiving the push the system launched it to deliver.

If push notifications are not being received,

Just to clarify, the pushes themselves are actually still reaching the device as normal. What changes here is how the system delivers them them to your app.

what should I do to resume receiving them?

The simplest way is to delete and reinstall the app. I believe callservicesd does reset this every ~24 hours, but that's not all that useful for an issue that should ONLY be occurring in a development app.

__
Kevin Elliott
DTS Engineer, CoreOS/Hardware

Additionally, if it occurs in a production environment, would reinstallation be a simple solution for recovery?

Yes, that's what I would recommend.

__
Kevin Elliott
DTS Engineer, CoreOS/Hardware

Is there a way for a device to detect when VoIP Push has been blocked?
 
 
Q