Hello,
I am developing Uniq Intercom, a voice-only group communication app for motorcyclists (always-on intercom over WebRTC, used continuously for multi-hour rides). I am seeking guidance on an iOS audio session and CarPlay HID interaction I have not been able to resolve through documented APIs.
Problem: As soon as my app activates the microphone (yellow recording indicator visible), iOS appears to classify the app as a real-time communication participant and CarPlay re-routes the steering-wheel / handlebar HID transport buttons (left / right / ok) from the media-control role to the call-control role (answer/decline). Because I do not register a CallKit / LiveCommunicationKit call (the session is a continuous group voice channel, not a discrete telephony call), there is no call object for those buttons to act upon — they effectively become inert.
Why this matters: Motorcyclists rely on the intercom for 4–6 hour rides. CarPlay is now built into a growing number of modern motorcycles and with aftermarket display units virtually any bike, and any rider who uses any voice communication platform alongside it — Uniq Intercom, WhatsApp Call currently runs into this same handlebar button remap. With the buttons inert, the rider's only remaining option is to reach for the motorcycle's touchscreen to skip a track or change navigation — this is unsafe. The exact same remap behavior occurs during a real WhatsApp or Phone call — but for those the remap is correct (answer/decline maps to a real call). For continuous voice apps without a CallKit-style discrete call, no equivalent path exists today. As both an iOS developer and a motorcyclist, I would very much like to see this resolved — solving it would meaningfully improve safety for every rider using an iPhone with CarPlay.
Configurations I have tested (all reproduce the symptom on iOS 18+ / 26 with wireless CarPlay):
AVAudioSession.Category.playAndRecord+.voiceChatmode + various option combinations (duckOthers,mixWithOthers,allowBluetoothHFP,allowBluetoothA2DP,defaultToSpeaker)- Same category with
.videoChatmode (which@livekit/react-nativedefaults to) - Same category with
.defaultmode (re-applied aftersetAudioModeAsyncto defeat any framework override) — confirmedMode = Defaultfor ~2 s window inaudiomxdlog before WebRTC'ssetActivecycle returned mode to.voiceChat. Buttons remained remapped during the.defaultwindow. - Disabling
MPRemoteCommandCenterand clearingMPNowPlayingInfoCenter.default().nowPlayingInfo - JS-side override of WebRTC's global
RTCAudioSessionConfigurationvia@livekit/react-native'sAudioSession.setAppleAudioConfiguration({audioMode: 'default'})bridge, applied both before connect and aftersetAudioModeAsyncto defeat library overrides
In every case the audiomxd system log confirms our session goes active (Mode = VoiceChat or Default, Recording = YES), and CarPlay HID buttons are immediately remapped to call-control. The middle "OK" button remains functional because it is not part of the call-control mapping — confirming the buttons are not blocked, only re-purposed. The remap occurs the instant the iOS recording indicator appears, regardless of audio session mode.
This led me to conclude the trigger is not audio session mode but the combination of microphone permission + active session + (likely) the AUVoiceIO unit instantiated by WebRTC. I cannot find a public API path to suppress this classification while maintaining the always-on continuous voice channel.
My questions:
- Is there an entitlement or API that allows an app with active microphone capture to declare itself as a non-call media participant, keeping CarPlay HID transport buttons in the media role?
- Is
AVAudioSession.setPrefersEchoCancelledInput(_:)(iOS 18+) the intended path for retaining platform AEC under.defaultmode without the focus-engine "communication priority" marking? Documentation is sparse on its CarPlay arbitration implications. - Does the
PushToTalkframework affect HID arbitration differently fromplayAndRecord + voiceChat? Our continuous-channel UX does not fit the PTT transmit-on-press model, but understanding the contrast would help. - If no current API exists, is this something the iOS Audio team would consider for future SDKs? Solving this would meaningfully improve safety for motorcycle and adventure-sport users on iOS.
Thank you for your time and any guidance you can offer.
— Emre Erkaya / Uniq Intercom
A note for any engineers reviewing this — variants of this AVAudioSession + CarPlay question have been posted on these forums for 4+ years now without substantive replies from framework engineers:
- https://developer.apple.com/forums/thread/680151 (May 2021)
- https://developer.apple.com/forums/thread/664874
- https://developer.apple.com/forums/thread/721535
- https://developer.apple.com/forums/thread/732202
- https://developer.apple.com/forums/thread/759379 (July 2024)
The recurring pattern suggests a real documentation gap, and it's becoming more relevant as motorcycle manufacturers ship CarPlay built-in (BMW, Honda, Harley-Davidson, KTM) and aftermarket displays like Chigee proliferate among riders. For motorcyclists, losing handlebar transport buttons mid-ride forces reaching for a touchscreen at speed — this is a real safety issue, not a UX nicety.
Any guidance, even a pointer to whether internal investigation is underway, would be appreciated. Happy to provide TestFlight builds, audiomxd logs, or test on beta SDKs.