From c472ee2618a65b54496edc884e92c0c3c3e58e0a Mon Sep 17 00:00:00 2001 From: sravan Date: Fri, 31 Jul 2026 18:24:54 +0530 Subject: [PATCH] Fix iOS build: use LiveKit 2.15.3 audio API (drop nonexistent setEngineAvailability) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The build failed: 'AudioManager' has no member 'setEngineAvailability' — that API is only on unreleased/main docs, not in the resolved LiveKitClient 2.15.3. Use the API that actually ships (per audio.md): disable LiveKit's automatic AVAudioSession configuration (AudioManager.shared.audioSession.isAutomaticConfigurationEnabled = false) and configure the session ourselves in CXProvider didActivate. Removed all setEngineAvailability(.none/.default) calls. Co-Authored-By: Claude Opus 4.8 --- mobile/plugins/native-call/NativeCall.podspec | 5 +++-- .../NativeCallPlugin/NativeCallPlugin.swift | 18 +++++++++--------- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/mobile/plugins/native-call/NativeCall.podspec b/mobile/plugins/native-call/NativeCall.podspec index c274b48..ccbc86b 100644 --- a/mobile/plugins/native-call/NativeCall.podspec +++ b/mobile/plugins/native-call/NativeCall.podspec @@ -18,8 +18,9 @@ Pod::Spec.new do |s| s.ios.deployment_target = '14.0' s.dependency 'Capacitor' # LiveKit iOS SDK — carries the call media NATIVELY so audio survives backgrounding AND coordinates with - # CallKit's audio session (AudioManager.setEngineAvailability on didActivate/didDeactivate), which the - # WebView's WebRTC could not do. Pulls in the WebRTC binary transitively. + # CallKit's audio session (auto-config OFF via AudioManager.shared.audioSession.isAutomaticConfigurationEnabled; + # we configure the session in CXProvider didActivate), which the WebView's WebRTC could not do. Pulls in the + # WebRTC binary transitively. s.dependency 'LiveKitClient', '~> 2.0' # CallKit + PushKit + AVFoundation are system frameworks (no external pod). s.frameworks = 'CallKit', 'PushKit', 'AVFoundation' diff --git a/mobile/plugins/native-call/ios/Sources/NativeCallPlugin/NativeCallPlugin.swift b/mobile/plugins/native-call/ios/Sources/NativeCallPlugin/NativeCallPlugin.swift index 00cadc0..103613f 100644 --- a/mobile/plugins/native-call/ios/Sources/NativeCallPlugin/NativeCallPlugin.swift +++ b/mobile/plugins/native-call/ios/Sources/NativeCallPlugin/NativeCallPlugin.swift @@ -55,12 +55,12 @@ public class NativeCallPlugin: CAPPlugin, CAPBridgedPlugin, PKPushRegistryDelega registry.desiredPushTypes = [.voIP] pushRegistry = registry - // CallKit audio coordination. LiveKit auto-configures & activates the AVAudioSession by default, which - // RACES CallKit's own activation → intermittent dead mic / no audio, and the output route only settling - // once audio starts flowing (the "speaker turns on late" symptom). Fix (per LiveKit's CallKit guide): - // disable auto-config, keep the audio engine OFF, and start it ONLY inside CXProvider didActivate. + // 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 - try? AudioManager.shared.setEngineAvailability(.none) } // MARK: - LiveKit media @@ -291,19 +291,19 @@ public class NativeCallPlugin: CAPPlugin, CAPBridgedPlugin, PKPushRegistryDelega action.fulfill() } - // CallKit owns the AVAudioSession lifecycle. Configure the session and START LiveKit's audio engine ONLY - // here (never before) — this is the fix for the intermittent dead mic / no-audio and late speaker routing. + // 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. public func provider(_ provider: CXProvider, didActivate audioSession: AVAudioSession) { do { try audioSession.setCategory(.playAndRecord, mode: .voiceChat, options: [.mixWithOthers]) - try AudioManager.shared.setEngineAvailability(.default) notifyListeners("audioActivated", data: ["ok": true]) } catch { notifyListeners("audioActivated", data: ["ok": false, "error": String(describing: error)]) } } public func provider(_ provider: CXProvider, didDeactivate audioSession: AVAudioSession) { - try? AudioManager.shared.setEngineAvailability(.none) // stop the engine until the next call's didActivate notifyListeners("audioDeactivated", data: ["ok": true]) } }