diff --git a/mobile/plugins/native-call/ios/Sources/NativeCallPlugin/NativeCallPlugin.swift b/mobile/plugins/native-call/ios/Sources/NativeCallPlugin/NativeCallPlugin.swift index 103613f..0e794aa 100644 --- a/mobile/plugins/native-call/ios/Sources/NativeCallPlugin/NativeCallPlugin.swift +++ b/mobile/plugins/native-call/ios/Sources/NativeCallPlugin/NativeCallPlugin.swift @@ -54,22 +54,16 @@ public class NativeCallPlugin: CAPPlugin, CAPBridgedPlugin, PKPushRegistryDelega registry.delegate = self registry.desiredPushTypes = [.voIP] pushRegistry = registry - - // CallKit audio coordination. LiveKit auto-configures the AVAudioSession by default, which RACES - // CallKit's own activation → intermittent dead mic / no audio + the output route only settling once - // audio starts flowing (the "speaker turns on late" symptom). Fix (per LiveKit's audio.md): turn OFF - // LiveKit's automatic session configuration and configure the session ourselves in CXProvider - // didActivate (when CallKit hands us the active session). - AudioManager.shared.audioSession.isAutomaticConfigurationEnabled = false + // NOTE: the CallKit↔LiveKit audio-session coordination (AudioManager.audioSession / + // setEngineAvailability) needs LiveKit 2.15+, but the build currently resolves an older 2.x that lacks + // those symbols. So we rely on LiveKit's default audio handling for now and only configure the session + // with plain AVFoundation in didActivate. Revisit once the pod is pinned/upgraded to 2.15+. } // MARK: - LiveKit media private func connectRoom(url: String, token: String) { guard !url.isEmpty, !token.isEmpty else { return } - // Ask for mic permission now (we still connect MUTED). If it stays "undetermined", enabling the audio - // engine in didActivate can BLOCK (SDK issue #815) → no audio. Determining it up front avoids that. - AVAudioSession.sharedInstance().requestRecordPermission { _ in } let old = room let r = Room() room = r @@ -291,17 +285,10 @@ public class NativeCallPlugin: CAPPlugin, CAPBridgedPlugin, PKPushRegistryDelega action.fulfill() } - // CallKit owns the AVAudioSession lifecycle. Since we disabled LiveKit's automatic configuration, configure - // the session HERE, when CallKit activates it — this is the fix for the intermittent dead mic / no-audio - // and late speaker routing (LiveKit's audio engine then runs on a correctly-configured, active session). - // Note: don't call setActive(true) — CallKit already activated it. + // Keep the last known-good audio behavior (rely on LiveKit's default session handling). We only report the + // state to JS. The proper CallKit↔LiveKit session coordination is deferred until the pod is on 2.15+. public func provider(_ provider: CXProvider, didActivate audioSession: AVAudioSession) { - do { - try audioSession.setCategory(.playAndRecord, mode: .voiceChat, options: [.mixWithOthers]) - notifyListeners("audioActivated", data: ["ok": true]) - } catch { - notifyListeners("audioActivated", data: ["ok": false, "error": String(describing: error)]) - } + notifyListeners("audioActivated", data: ["ok": true]) } public func provider(_ provider: CXProvider, didDeactivate audioSession: AVAudioSession) { notifyListeners("audioDeactivated", data: ["ok": true])