Audio route control
On iOS, PlanetKit classifies the current audio output route as the built-in handset, built-in speakerphone, or an external headset. It can request or release built-in speakerphone output and notify your app when the route changes.
| Supported call type | Minimum SDK version |
|---|---|
| 1-to-1 call, group call (conference) | PlanetKit 6.0 |
- Audio route control is an iOS-only feature. On macOS, use the audio device selection feature instead.
- PlanetKit does not directly select external output devices. Use AVRoutePickerView to let users choose one.
Audio route values
PlanetKit classifies the current output route using PlanetKitAudioRoute:
| Value | Description |
|---|---|
.builtInHandset | Phone earpiece |
.builtInSpeakerphone | Phone speakerphone |
.externalHeadset | Wired or Bluetooth headset |
- PlanetKit does not provide a synchronous property for reading the current
PlanetKitAudioRoute, and reports output-route changes asPlanetKitAudioRoutevalues throughPlanetKitAudioRouteChangeDelegate. For more information, see "Observe audio route changes". - To inspect the port-level input and output details of the current audio route, use Apple's
AVAudioSession.currentRouteAPI.
Switch to speakerphone
Use PlanetKitAudioSession.speakerOut(_:) to request built-in speakerphone output or release that request.
let session = PlanetKitAudioManager.shared.session
// Request speakerphone output asynchronously.
session.speakerOut(true)
// Release the speakerphone request asynchronously and let iOS choose the route.
session.speakerOut(false)
// Read the current output state; pending requests may not yet be reflected.
let isSpeakerOn = session.isSpeakerOut
Speakerphone output requests are temporary output overrides, and iOS can reset them when the audio route changes. If the route changes to an external device, PlanetKit does not reapply a prior speakerphone request. See Apple QA1754 for output-override behavior.
Automatic default-route adjustment
By default, PlanetKit automatically adjusts the built-in route for calls. If a call starts on the built-in handset, an audio call stays on the handset and a video call requests the built-in speakerphone. This automatic adjustment does not choose an external device.
To disable this automatic adjustment, configure the initial setting before you initialize PlanetKit:
let initialSettings = PlanetKitInitialSettingBuilder()
.withDisableDefaultAudioRouteKey(disable: true)
.build()
PlanetKitManager.shared.initialize(initialSettings: initialSettings)
Set disable to true only if your app does not want PlanetKit to make those automatic built-in-route adjustments. The default is false. Releasing an app speakerphone request with speakerOut(false) does not disable automatic default-route adjustment.
When automatic adjustment is enabled, enabling the video call requests speakerphone only if the current route is the built-in handset. Built-in speakerphone and external headset routes are retained. Disabling the video call does not by itself change the route. If a connected video call falls back from an external headset to the built-in handset, PlanetKit requests the speakerphone.
Observe audio route changes
PlanetKit handles audio route changes internally to keep audio flowing correctly. Implement this delegate only if your app needs to update its UI in response — for example, to refresh a speakerphone toggle button.
Register a PlanetKitAudioRouteChangeDelegate to be notified when the route changes (for example, when a headset is plugged in or unplugged).
final class MyRouteObserver: PlanetKitAudioRouteChangeDelegate {
func didAudioRouteChange(current: PlanetKitAudioRoute, previous: PlanetKitAudioRoute) {
print("Route changed from \(previous) to \(current)")
// Update UI — e.g., refresh speakerphone button state
}
}
final class CallViewController: UIViewController {
// PlanetKit retains route delegates weakly, so retain this observer strongly.
private let routeObserver = MyRouteObserver()
func startObservingRouteChanges() {
PlanetKitAudioManager.shared.addAudioRouteChangeDelegate(routeObserver)
}
deinit {
PlanetKitAudioManager.shared.removeAudioRouteChangeDelegate(routeObserver)
}
}
The delegate is called on the main queue.
Related APIs
APIs related to audio route control are as follows.
Enum
Properties
Methods
-
addAudioRouteChangeDelegate(_:)ofPlanetKitAudioManager -
removeAudioRouteChangeDelegate(_:)ofPlanetKitAudioManager -
speakerOut(_:)ofPlanetKitAudioSession -
withDisableDefaultAudioRouteKey(disable:)ofPlanetKitInitialSettingBuilder