PushKit sometime not returning VoIP token

We are implementing PushKit/CallKit for audio video calls.

When the app starts, it immediately in AppDelegate-didFinishLaunchingWithOptions create the PKPushRegistry, set the delegate and ask for the token with desiredPushTypes and upload the token to our backend when PKPushCredentials are received. Then when didReceiveIncomingPushWith is called, it directly reports the call to CallKit.

That works fine on all devices, with the app in foreground, background, killed etc..

But on one slow device (iPhone 7, iOS 15.6.1) when the app has been killed for some time, the app do not receive anymore the token. Then at some point PushKit doesn't wake the app anymore, as CallKit was not notified.

According to the console logs by filtering callservicesd, the time between receiving the PushKit notification being received and delivering the token changes a lot, and then can timeout:

Successful call:

default	15:00:58.181051+0200	callservicesd	Received incoming APS message from application with bundle identifier <private> and topic <private>
// ...
default	15:01:00.627903+0200	callservicesd	Delivering token <private> to application <private>

So 2 seconds.

Failing call:

default	14:13:20.325371+0200	callservicesd	Received incoming APS message from application with bundle identifier <private> and topic <private>
// ...
default	14:13:28.827702+0200	callservicesd	Delivering token <private> to application <private>
// ...
default	14:13:32.325062+0200	callservicesd	Invalidating process assertion for bundle ID <private> from timeout

8 seconds. Even if "callservicesd Delivering token" is written in the logs, the app do not receive it.

Then for the failing call, as didUpdate pushCredentials and didReceiveIncomingPushWith are not called, the app get killed:

default	14:13:32.326334+0200	runningboardd	Invalidating assertion 33-134-19180 (target:[application<myAppId>:1363]) from originator [daemon<com.apple.telephonyutilities.callservicesd>:134]
default	14:13:32.393456+0200	runningboardd	Received termination request from [daemon<com.apple.telephonyutilities.callservicesd>:134] on <RBSProcessPredicate <RBSProcessIdentityPredicate| application<myAppId>>> with context <RBSTerminateContext| domain:10 code:0xBAADCA11 explanation:<no explanation given> reportType:CrashLog maxTerminationResistance:Interactive>
error	14:13:32.404027+0200	callservicesd	Killing VoIP app <private> because it failed to post an incoming call in time.

Is there any way to make sure that the token and the VoIP push will be delivered in time and not be killed by iOS, even on slow device?

Post not yet marked as solved Up vote post of md_td Down vote post of md_td
1.5k views

Replies

  1. Make sure PKPushRegistry is called in the main thread and the delegate queue is set to the main thread
  2. Make sure that Callkit reportIncomingCall is called in time in the didReceiveIncomingPushWith callback. If it is not called multiple times, it will be blacklisted by the system.

Thanks for your answer crystal_matrx

  1. All is done in the main thread, init and queue.

  2. As I wrote, the VoIP token and the PushKit notification are not delivered in the app in time, so CallKit cannot be called (and that before it happens too many times and PushKit stops waking up the app).

After more research and speaking with Apple Developer Technical Support there seems to be 2 problems, linked with the app startup time:

1 - Too much time spent in AppDelegate didFinishLaunchingWithOptions

Delaying all services creation (firebase etc.) to later (like in viewDidAppear of initial UIViewControler) helped to display CallKit more often, but not always because of the second point.

2 - Too much time to reach AppDelegate didFinishLaunchingWithOptions

Using profiling and AppLaunch, on my old device dyld can take a lot of time and sometime according to logs the app doesn't even reach didFinishLaunchingWithOptions before being killed by callservicesd. This part is still not clear, that can be due to being in a debug environment, making build configuration as "Release" and disabling as many options as possible did not help.

So even if point 1 helped, on a slow device unplugged with locked screen, the app being killed and a few heavy apps started before, sometime VoIP pushes still do not reach the point to display CallKit. Maybe a full release build will solve the problem of point 2., something I could not try yet using TestFlight due to VoIP backend not being in prod yet.

Has there been update on this? I am facing a similar issue.