Critical CallKit Issue: Audio Route Flapping due to reason: 3 (CategoryChange) after User Toggle

I am facing a severe audio routing instability issue when using CallKit and the Zego Express SDK on iOS. The problem is that the audio route immediately reverts from the Speaker back to the Earpiece, effectively disabling the Speaker button functionality.📝 Observed BehaviorWhen the user taps the native CallKit Speaker Button, the audio route is correctly changed to the Speaker, but then instantly flips back to the Receiver (Earpiece), as shown in the system log captured via AVAudioSession.routeChangeNotification monitoring.🧾 Log Evidence (Flapping Occurs in 0.4 seconds)The following log snippet clearly illustrates the system overriding the user's action (reason: 4) with an unexpected CategoryChange (reason: 3) event:

TimestampComponentReason CodeDescriptionRouteIs

Speaker16:31:18.009[CallKitManager]4Override (CallKit/ControlCenter)Loa ngoài

(Speaker)true16:31:18.411[CallKitManager]3CategoryChangeThiết bị nhận (Receiver)false

I am facing a severe audio routing instability issue when using CallKit and the Zego Express SDK on iOS. The problem is that the audio route immediately reverts from the Speaker back to the Earpiece, effectively disabling the Speaker button functionality. 📝

Are you able to reproduce the problem in our sample code (Speakerbox)?

Observed BehaviorWhen the user taps the native CallKit Speaker Button, the audio route is correctly changed to the Speaker, but then instantly flips back to the Receiver (Earpiece), as shown in the system log captured via AVAudioSession.routeChangeNotification monitoring. 🧾 Log Evidence (Flapping Occurs in 0.4 seconds)The following log snippet clearly illustrates the system overriding the user's action (reason: 4) with an unexpected CategoryChange (reason: 3) event:

I think this is a problem with the library, specifically because of this:

"with an unexpected CategoryChange (reason: 3) event:"

CallKit is tightly integrated with the audio system because the audio session that calls actually uses ISN'T the standard "PlayAndRecord" audio category. It's a special "Phone" audio category that has higher priority and slightly louder volume than a standard PlayAndRecord session. It also can't be directly activated by your app, which is why it's critical that VoIP apps manage their audio session in the same way our sample project does. That means:

  • The session must be fully configured as early as possible, before calls are started or reported.

  • The app must not directly activate the session, aside from the interruption case shown in the sample.

  • Most session changes cannot occur while the call is active.

Failure to follow these guidelines will result in exactly the kinds of failures you're describing. Finally, as a general point, my expectation is that every VoIP library that claims to support iOS should include CallKit and/or LiveCommunicationKit support. Those APIs are a fundamental part of how VoIP apps "work" on our platform, so a VoIP SDK that chooses to integrate them doesn't really "work". More to the point, one of two things is true:

  • Their library can easily integrate with these APIs, in which case it's easy for the vendor to directly support these APIs in their SDK.

OR

  • Their library cannot easily integrate with these APIs, in which case the library isn't really a viable VoIP SDK on iOS.

__
Kevin Elliott
DTS Engineer, CoreOS/Hardware

Critical CallKit Issue: Audio Route Flapping due to reason: 3 (CategoryChange) after User Toggle
 
 
Q