PLATFORM AND VERSION
iOS Development environment: Xcode 15.0, macOS 14.4.1, Objective-C
Run-time configuration: iOS 17.2.1,
DESCRIPTION OF PROBLEM
I am developing an application that uses NetworkExtension (VoIP local push function). But iOS sometimes doesn't call didActivateAudioSession after following sequence. Would you tell me why iOS doesn't call didActivateAudioSession ? (I said "sometimes", but once it occurs, it will occur repeatedly)
- myApp --- CXStartCallAction --->iOS
- myApp <-- performStartCallAction callback --- iOS
- myApp --- AVAudioSession setCategory: AVAudioSessionCategoryPlayAndRecord --->iOS
- myApp --- AVAudioSession setMode: AVAudioSessionModeVoiceChat --->iOS
- myApp <-- didActivateAudioSession callback ----iOS
I suspect that myApp cannot acquire an AVAudioSession if another app is already using AVAudioSession.
[QUESTION1]
Is my guess correct? Should I consider another cause?
[QUESTION2]
If my guess is correct, how can I prove if another app is already using an AVAudioSession? This issue is based on a customer complaint, but the customer said they don't use any other apps.
Best Regards,
I am developing an application that uses NetworkExtension (VoIP local push function). But iOS sometimes doesn't call didActivateAudioSession after following sequence. Would you tell me why iOS doesn't call didActivateAudioSession ? (I said "sometimes", but once it occurs, it will occur repeatedly)
So, first and foremost, please review the "VoIP calling with CallKit". CallKit is closely entangled with the audio system and must be configured and controlled in exactly the way that sample shows. Incorrect usage will cause a variety of failures, including the one you're seeing.
Moving to your specific issue, the problem with this sequence here:
1. myApp --- CXStartCallAction --->iOS
2. myApp <-- performStartCallAction callback --- iOS
3. myApp --- AVAudioSession setCategory: AVAudioSessionCategoryPlayAndRecord --->iOS
4. myApp --- AVAudioSession setMode: AVAudioSessionModeVoiceChat --->iOS
5. myApp <-- didActivateAudioSession callback ----iOS
...is that you were trying to configure the AudioSession "to late". CallKit modifies your audio session as well as activating it and attempting to modify it after the call sequence has already started won't work (See below).
I suspect that myApp cannot acquire an AVAudioSession if another app is already using AVAudioSession.
Is my guess correct? Should I consider another cause?
No, or at least not in the way you mean.
The audio session category CallKit activates is NOT a "standard" AVAudioSessionCategoryPlayAndRecord category, but a "special" phone specific session. As an aside here, you can confirm this by listening closely to the maximum volume of a CallKit session vs. a standard AVAudioSessionCategoryPlayAndRecord. The CallKit session will be noticeably louder than the standard session.
In any case, that specific session type what CallKit uses to activate a recording session in the background, something which a standard session cannot. When you attempt to modify the category at the wrong time, one of two failures occur:
-
IF the session is not active, you can disrupt CallKit's session activation process, causing the session to fail.
-
IF the session IS active, then the category change will simply fail, since you cannot change the category configuration of an active session.
One other point to understand here is that not only is incorrect:
I suspect that myApp cannot acquire an AVAudioSession if another app is already using AVAudioSession.
...but the actual behavior is in fact the OPPOSITE of that. That is, NONE of the standard audio session types can interfere with the CallKit AudioSession. That is, it has higher activation priority than EVERY other audio session type on the system and CANNOT be interrupted by any of the public session categories. Audio issues inside CallKit apps are caused by how the app has configured "itself" because nothing else on the system has a high enough priority to interfere with the CallKit session. This is also why CallKit has its own system for switching between calls- CallKit has to coordinate between CallKit apps because the audio system itself won't let them directly interrupt each other.
Finally, keep in mind that Phone.app and Facetime are also CallKit apps. In terms of the audio layer, they're using the same API and have the same capabilities you have. If you're seeing very different audio behavior than they are, it's because of how you're using the API, not because they have additional abilities.
__
Kevin Elliott
DTS Engineer, CoreOS/Hardware