provider(_:didActivate:) callback intermittently not triggered, causing widespread audio loss for users

Hi everyone,

I am facing a critical issue where the CallKit provider delegate method provider(_:didActivate:) is intermittently not triggered. This occasionally results in a total loss of audio during some VoIP calls, while other calls work perfectly fine.

Here is the sequence of steps I am currently implementing:

  1. Report Incoming Call: The app receives a VoIP push notification and reports the call using reportNewIncomingCall(with:update:completion:).

  2. Answer Action: The user taps the answer button, and the app processes the CXAnswerCallAction.

  3. Configure Audio Session: Inside the provider delegate, I configure the AVAudioSession category and mode (e.g., setting category to .playAndRecord and mode to .voiceChat). Note: As per Apple's guidelines, I do not call setActive(true) manually, expecting CallKit to activate it automatically.

Despite following this standard flow, there are times when provider(_:didActivate:) is skipped entirely, meaning the audio engine fails to initialize for that specific call session.

We are currently receiving a large volume of user complaints regarding this issue, as it heavily impacts the core calling experience in production.

Could an Apple engineer or anyone from the community look into this? Any insights into what might be causing CallKit to occasionally fail to activate the audio session or how to work around this would be highly appreciated.

Thank you!

Answered by DTS Engineer in 895166022

Could an Apple engineer or anyone from the community look into this? Any insights into what might be causing CallKit to occasionally fail to activate the audio session or how to work around this would be highly appreciated.

So, a few things I'd note. First off, on this point:

Configure Audio Session: Inside the provider delegate,

This is the same point Speakerbox calls "configureAudioSession", however, if you look closely at Speakerbox's implementation you'll realize that it only actually "does" anything the very first time configureAudioSession is called. The rest of the time it does "nothing“ - like most apps, it's audio session configuration never changes so there's no reason to actually do the same configuration all over again.

These details are important because the internal logic of how the session is managed gets very complicated once your app is handling multiple calls. Most apps should probably just reuse Speakerbox’s implementation, but if you're writing your own I would recommend really looking closely at exactly what our code is doing.

Having said that, what you're describing here:

I am facing a critical issue where the CallKit provider delegate method provider(_:didActivate:) is intermittently not triggered.

Sounds like the same issue reported on this thread. I also describe a simple workaround in that same thread here, which is to simply call "setConfiguration" before every call report. I can't promise it will resolve all of these issues, but the reports I have seen show it making a very significant difference.

Finally, if you have a moment I'd appreciate you filing your own bug about this and, if possible, including concrete numbers about the call failure rate/count. I'd like the system to address this and a big part of that is getting more concrete data about the bug’s impact.

__
Kevin Elliott
DTS Engineer, CoreOS/Hardware

Accepted Answer

Could an Apple engineer or anyone from the community look into this? Any insights into what might be causing CallKit to occasionally fail to activate the audio session or how to work around this would be highly appreciated.

So, a few things I'd note. First off, on this point:

Configure Audio Session: Inside the provider delegate,

This is the same point Speakerbox calls "configureAudioSession", however, if you look closely at Speakerbox's implementation you'll realize that it only actually "does" anything the very first time configureAudioSession is called. The rest of the time it does "nothing“ - like most apps, it's audio session configuration never changes so there's no reason to actually do the same configuration all over again.

These details are important because the internal logic of how the session is managed gets very complicated once your app is handling multiple calls. Most apps should probably just reuse Speakerbox’s implementation, but if you're writing your own I would recommend really looking closely at exactly what our code is doing.

Having said that, what you're describing here:

I am facing a critical issue where the CallKit provider delegate method provider(_:didActivate:) is intermittently not triggered.

Sounds like the same issue reported on this thread. I also describe a simple workaround in that same thread here, which is to simply call "setConfiguration" before every call report. I can't promise it will resolve all of these issues, but the reports I have seen show it making a very significant difference.

Finally, if you have a moment I'd appreciate you filing your own bug about this and, if possible, including concrete numbers about the call failure rate/count. I'd like the system to address this and a big part of that is getting more concrete data about the bug’s impact.

__
Kevin Elliott
DTS Engineer, CoreOS/Hardware

Hi [DTS Engineer's],

Thank you for your previous recommendations. We have successfully implemented them, but unfortunately, the core issue persists with a critical symptom.

We performed a comparative analysis with other communication apps like WhatsApp, Zalo, and Telegram under the same scenario. On those platforms, the audio failure only occurs temporarily for a single call; subsequent incoming or outgoing calls recover and function normally.

However, with our app, once the audio is lost, it remains completely silent for all subsequent calls. The only way to restore audio functionality is to force-kill and restart the app.

This behavior is causing a severe degradation of our user experience and is considered a critical blocker for our production app.

Do you have any further recommendations or insights into what might be causing our audio session (or audio graph) to latch into this unrecoverable state?

Thank you for your continued support.

When the audio stopped working, the entire call audio system malfunctioned. Apps like WhatsApp and Phone were affected, but Zalo was still able to make calls. The device must be restarted before it can be used again.

Do you have any further recommendations or insights into what might be causing our audio session (or audio graph) to latch into this unrecoverable state?

Have you implemented the workaround I recommended in the post above:

Sounds like the same issue reported on this thread. I also describe a simple workaround in that same thread here, which is to simply call "setConfiguration" before every call report. I can't promise it will resolve all of these issues, but the reports I have seen show it making a very significant difference.

Note that EXACTLY how other apps will behave depends ENTIRELY on the details of that app’s particular implementation and behavior. In the case I've specifically been able to directly investigate, what actually happens here:

When the audio stopped working, the entire call audio system malfunctioned. Apps like WhatsApp and Phone were affected, but Zalo was still able to make calls.

...is that a system-wide failure (typically, a mediaserverd crash) disrupted the audio system. The audio system itself was able to recover and could "work" (which is why things like force quitting worked), but the behavior of individual apps depended on the specific details of their implementation. In practice, that's tended to mean:

  • Many apps had similar behavior, as their core CallKit code was actually copied from our CallKit sample.

  • The differences that do occur are either caused by differences in circumstance (for example, the system terminating an app for unrelated reasons) or implementation choices.

As an example of that second point, some apps choose to exit/abort at the point they determine that they're "broken" to the point that they're not able to properly activate the call. That isn't something I'd necessarily recommend, but it does mean that future calls will trigger a full app launch, which does improve the likelihood that the "next" call will succeed.

__
Kevin Elliott
DTS Engineer, CoreOS/Hardware

provider(_:didActivate:) callback intermittently not triggered, causing widespread audio loss for users
 
 
Q