### Setup Data Channel Encryption Source: https://github.com/livekit/client-sdk-swift/blob/main/_autodocs/api-reference/Encryption.md Example demonstrating how to set up data channel encryption by creating an EncryptionOptions object and passing it to RoomOptions. ```APIDOC ### Setup ```swift let encryptionOptions = EncryptionOptions( keyProvider: MyEncryptionKeyProvider() ) let roomOptions = RoomOptions(encryptionOptions: encryptionOptions) try await room.connect( url: url, token: token, roomOptions: roomOptions ) ``` ``` -------------------------------- ### SwiftUI Usage Example Source: https://github.com/livekit/client-sdk-swift/blob/main/_autodocs/api-reference/VideoView.md Instantiate a VideoView for use in SwiftUI. Assign a video track to start rendering. ```swift let videoView = VideoView() videoView.track = remoteVideoTrack ``` -------------------------------- ### start() Source: https://github.com/livekit/client-sdk-swift/blob/main/_autodocs/api-reference/Tracks.md Starts the track, initiating media capture or reception. This method is asynchronous and can throw a LiveKitError. ```APIDOC ## start() ### Description Starts the track (begins capturing or receiving media). ### Method `async throws` ### Throws `LiveKitError` ``` -------------------------------- ### iOS Screen Sharing Setup Source: https://github.com/livekit/client-sdk-swift/blob/main/_autodocs/api-reference/ScreenSharing.md Example of how to set up the Broadcast Upload Extension for screen sharing on iOS using ReplayKit and BroadcastManager. ```APIDOC ## iOS Screen Sharing Setup ### Description This code demonstrates the setup for screen sharing on iOS using the ReplayKit framework and a broadcast extension. It shows how to integrate `BroadcastManager` within the `SampleHandler` to manage the broadcast lifecycle. ### Usage 1. **Create a Broadcast Upload Extension Target** in Xcode. 2. **Implement the `SampleHandler` class** as shown below: ```swift import LiveKit class SampleHandler: RPBroadcastSampleHandler { var broadcastManager = BroadcastManager.shared override func broadcastStarted(withSetupInfo setupInfo: [String: NSObject]?) { broadcastManager.start() } override func broadcastPaused() { broadcastManager.pause() } override func broadcastResumed() { broadcastManager.resume() } override func broadcastFinished() { broadcastManager.stop() } override func processSampleBuffer(_ sampleBuffer: CMSampleBuffer, withType sampleBufferType: RPSampleBufferType) { broadcastManager.process(sampleBuffer: sampleBuffer, type: sampleBufferType) } } ``` ### Notes - Ensure `BroadcastManager.shared` is properly initialized and configured elsewhere if needed. - The SDK automatically handles track lifecycle when screen sharing is started or stopped via Control Center. ``` -------------------------------- ### ConnectOptions Example Source: https://github.com/livekit/client-sdk-swift/blob/main/_autodocs/configuration.md Demonstrates how to instantiate and use ConnectOptions to customize room connection settings. This example shows setting custom reconnection attempts, delay, ICE servers, and enabling the microphone. ```swift let connectOptions = ConnectOptions( autoSubscribe: true, reconnectAttempts: 5, reconnectAttemptDelay: 0.5, reconnectMaxDelay: 10, iceServers: [IceServer(urls: ["stun:stun.l.google.com:19302"])], enableMicrophone: true ) try await room.connect( url: "wss://livekit.example.com", token: token, connectOptions: connectOptions ) ``` -------------------------------- ### Dimensions Example Source: https://github.com/livekit/client-sdk-swift/blob/main/_autodocs/types.md An example of how to create a `Dimensions` struct for HD video. ```swift let hd = Dimensions(width: 1280, height: 720) ``` -------------------------------- ### SimpleKeyProvider Example Implementation Source: https://github.com/livekit/client-sdk-swift/blob/main/_autodocs/api-reference/Encryption.md An example implementation of the E2EEKeyProvider protocol. It derives keys from a master key and participant identity using SHA256. ```swift class SimpleKeyProvider: E2EEKeyProvider { private let masterKey: Data init(masterKey: Data) { self.masterKey = masterKey } func keyForParticipant(_ participantIdentity: String, keyIndex: Int) async throws -> Data { // Derive key from master key and participant identity var hasher = SHA256() hasher.update(data: masterKey) hasher.update(data: participantIdentity.data(using: .utf8)!) hasher.update(data: Data(withUnsafeBytes(of: keyIndex) { $0 })) return Data(hasher.finalize()) } func ratchetKey(participantIdentity: String) async throws { // Advance key index for forward secrecy // Implementation depends on your key management strategy } } ``` -------------------------------- ### Start Track Source: https://github.com/livekit/client-sdk-swift/blob/main/_autodocs/api-reference/Tracks.md Starts the track, initiating media capture or reception. Throws LiveKitError on failure. ```swift public func start() async throws ``` -------------------------------- ### Example Usage of RoomDelegate Source: https://github.com/livekit/client-sdk-swift/blob/main/_autodocs/api-reference/Delegates.md Demonstrates how to implement and register a RoomDelegate with a Room instance. This shows how to handle connection and participant join events. ```swift extension MyViewController: RoomDelegate { func roomDidConnect(_: Room) { print("Connected to room") } func room(_: Room, participantDidJoin participant: RemoteParticipant) { updateParticipantList() } } let room = Room() room.delegates.add(delegate: self) ``` -------------------------------- ### Create and Publish Local Audio Track Source: https://github.com/livekit/client-sdk-swift/blob/main/_autodocs/api-reference/Tracks.md Creates a new local audio track with optional capture options and starts publishing it to a room. Ensure the track is started before publishing. ```swift let audioTrack = LocalAudioTrack.createTrack( options: AudioCaptureOptions(echoCancellation: true) ) try await audioTrack.start() let publication = try await localParticipant.publish(audioTrack: audioTrack) ``` -------------------------------- ### Ratchet Key Example Source: https://github.com/livekit/client-sdk-swift/blob/main/_autodocs/api-reference/Encryption.md Example of how to call the ratchetKey method on an E2EEKeyProvider to advance encryption keys for forward secrecy. ```swift try await keyProvider.ratchetKey(participantIdentity: participant.identity!) ``` -------------------------------- ### UIKit Usage Example Source: https://github.com/livekit/client-sdk-swift/blob/main/_autodocs/api-reference/VideoView.md Instantiate and add a VideoView to a UIKit view hierarchy. Configure constraints and assign a video track. ```swift let videoView = VideoView() view.addSubview(videoView) // Configure constraints... videoView.track = remoteVideoTrack ``` -------------------------------- ### Creating E2EE Room Source: https://github.com/livekit/client-sdk-swift/blob/main/_autodocs/api-reference/Encryption.md Example of how to create a RoomOptions object with E2EEOptions and connect to a room. ```APIDOC ## Creating E2EE Room ```swift let e2eeOptions = E2EEOptions(keyProvider: MyKeyProvider()) let roomOptions = RoomOptions(e2eeOptions: e2eeOptions) try await room.connect( url: url, token: token, roomOptions: roomOptions ) ``` ``` -------------------------------- ### Running a Development LiveKit Server Source: https://github.com/livekit/client-sdk-swift/blob/main/Tests/LKTestHost/README.md Start a local LiveKit development server. Ensure to set the LIVEKIT_TESTING_URL environment variable to the server's address. ```sh livekit-server --dev --bind 0.0.0.0 # Set `LIVEKIT_TESTING_URL` to `ws://:7880` ``` -------------------------------- ### Basic Video Call Setup Source: https://github.com/livekit/client-sdk-swift/blob/main/_autodocs/README.md Connect to a LiveKit room, publish local camera and microphone tracks, and subscribe to remote video tracks. Requires a RoomDelegate implementation. ```swift import LiveKit import UIKit class VideoCallViewController: UIViewController, RoomDelegate { let room = Room(delegate: self) let videoView = VideoView() override func viewDidLoad() { super.viewDidLoad() view.addSubview(videoView) // Configure constraints... } @IBAction func connect() { Task { try await room.connect(url: "wss://your-host", token: yourToken) try await room.localParticipant.setCamera(enabled: true) try await room.localParticipant.setMicrophone(enabled: true) } } func room(_: Room, participant: RemoteParticipant, didSubscribeTrack publication: RemoteTrackPublication) { if let videoTrack = publication.videoTrack { DispatchQueue.main.async { self.videoView.track = videoTrack } } } @IBAction func disconnect() { Task { await room.disconnect() } } } ``` -------------------------------- ### Install LiveKit with CocoaPods Source: https://github.com/livekit/client-sdk-swift/blob/main/Docs/cocoapods.md Add this configuration to your Podfile to install the LiveKit client. Ensure you include both the default CocoaPods source and the LiveKit-specific podspecs repository. This method is deprecated and migration to Swift Package Manager is recommended. ```ruby source "https://cdn.cocoapods.org/" source "https://github.com/livekit/podspecs.git" # <- platform :ios, "18.0" target "YourApp" do pod "LiveKitClient", "~> 2.2.0" # Other dependencies... end ``` -------------------------------- ### LocalTrackPublication Properties and Example Source: https://github.com/livekit/client-sdk-swift/blob/main/_autodocs/api-reference/TrackPublications.md Details the properties specific to local track publications, including convenience accessors for audio and video tracks, and provides an example of how to access and configure a published video track. ```APIDOC ## LocalTrackPublication Represents a locally published track. ### Access ```swift let publications: [LocalTrackPublication] = room.localParticipant.localAudioTracks let videoPublications: [LocalTrackPublication] = room.localParticipant.localVideoTracks ``` ### Properties (in addition to base) #### audioTrack ```swift public var audioTrack: LocalAudioTrack? { track as? LocalAudioTrack } ``` Convenience accessor for audio tracks. #### videoTrack ```swift public var videoTrack: LocalVideoTrack? { track as? LocalVideoTrack } ``` Convenience accessor for video tracks. ### Example Usage ```swift // Access published video track if let videoPublication = localParticipant.localVideoTracks.first, let videoTrack = videoPublication.videoTrack { // Configure track videoTrack.processor = myProcessor videoTrack.add(videoRenderer: myRenderer) } ``` ``` -------------------------------- ### Run LiveKit SDK Tests Source: https://github.com/livekit/client-sdk-swift/blob/main/AGENTS.md Runs unit and E2E tests for the LiveKit SDK on macOS. Requires a local LiveKit server. Install it via `brew install livekit`. ```zsh # Run tests (requires local server: livekit-server --dev, install via brew install livekit) xcodebuild test -scheme LiveKit -only-testing LiveKitCoreTests -destination 'platform=macOS' ``` -------------------------------- ### Start Audio Recording Source: https://github.com/livekit/client-sdk-swift/blob/main/_autodocs/api-reference/AudioManager.md Manually start the audio recording device. This function may throw errors related to the audio engine or session configuration. ```swift try await AudioManager.shared.startRecording() ``` -------------------------------- ### Key Rotation Example Source: https://github.com/livekit/client-sdk-swift/blob/main/_autodocs/api-reference/Encryption.md Illustrates how to implement key rotation using a Timer to periodically call ratchetKey for all remote participants, ensuring forward secrecy. ```APIDOC ### Key Rotation Regularly ratchet keys for forward secrecy: ```swift // Ratchet keys every minute Timer.scheduledTimer(withTimeInterval: 60, repeats: true) { _ in Task { for participant in room.remoteParticipants.values { try? await keyProvider.ratchetKey( participantIdentity: participant.identity! ) } } } ``` ``` -------------------------------- ### ScreenShareCaptureOptions Example Source: https://github.com/livekit/client-sdk-swift/blob/main/_autodocs/api-reference/ScreenSharing.md Instantiate ScreenShareCaptureOptions to specify screen resolution and frame rate for screen sharing. A recommended FPS of 5 is often suitable. ```swift let options = ScreenShareCaptureOptions( dimensions: Dimensions(width: 1920, height: 1080), fps: 5 ) ``` -------------------------------- ### Audio Device Selection Source: https://github.com/livekit/client-sdk-swift/blob/main/_autodocs/api-reference/AudioManager.md Control the starting and stopping of the audio recording device. ```APIDOC ## Audio Device Selection ### startRecording() ```swift public func startRecording() async throws ``` Starts the audio recording device. **Throws:** `LiveKitError.audioEngine` or `.audioSession` ### stopRecording() ```swift public func stopRecording() async throws ``` Stops the audio recording device. **Throws:** `LiveKitError` ``` -------------------------------- ### Make an RPC Call and Handle Response Source: https://github.com/livekit/client-sdk-swift/blob/main/_autodocs/api-reference/DataStreams.md Example of making an RPC call to an agent with JSON data and handling the response. Includes error handling for timeouts and decoding issues. ```swift let request = try JSONEncoder().encode(["action": "greet", "name": "Alice"]) do { let responseData = try await localParticipant.rpc( method: "handleGreeting", to: agentIdentity, data: request, responseTimeout: 5.0 ) let response = try JSONDecoder().decode( GreetingResponse.self, from: responseData ) print("Response: \(response.message)") } catch let error as LiveKitError { if error.type == .timedOut { print("RPC call timed out") } } ``` -------------------------------- ### MulticastDelegate Usage Source: https://github.com/livekit/client-sdk-swift/blob/main/_autodocs/api-reference/Delegates.md Example of using a generic MulticastDelegate to manage and notify multiple listeners of events. ```swift public class MulticastDelegate: Sendable { public func add(delegate: T) public func remove(delegate: T) public func notify(_ closure: (T) -> Void) } let delegates = MulticastDelegate(label: "RoomDelegate") // Add delegate delegates.add(delegate: myDelegate) // Notify all delegates delegates.notify { $0.roomDidConnect(room) } ``` -------------------------------- ### Build LiveKit SDK Source: https://github.com/livekit/client-sdk-swift/blob/main/AGENTS.md Builds the LiveKit SDK for macOS. Ensure you have Xcode installed. ```zsh # Build xcodebuild build -scheme LiveKit -destination 'platform=macOS' ``` -------------------------------- ### Publishing Screen Share Track Source: https://github.com/livekit/client-sdk-swift/blob/main/_autodocs/api-reference/ScreenSharing.md Steps to create, start, and publish a screen share video track to a LiveKit room. ```APIDOC ## Publishing Screen Share Track ### Description This section details the process of creating a screen share video track, starting it, and then publishing it to the LiveKit room. It includes recommended options for publishing screen share content. ### Steps 1. **Create the Screen Share Track**: Use `LocalVideoTrack.createScreenShareTrack()` with desired `ScreenShareCaptureOptions`. 2. **Start the Track**: Call `start()` on the created track. 3. **Publish the Track**: Use `localParticipant.publish()` with appropriate `VideoPublishOptions`. ### Example ```swift // 1. Create the screen share track with specific FPS let screenTrack = try await LocalVideoTrack.createScreenShareTrack( options: ScreenShareCaptureOptions(fps: 5) ) // 2. Start the track try await screenTrack.start() // 3. Define publishing options (e.g., max bitrate, disable simulcast) let publishOptions = VideoPublishOptions( encoding: VideoEncoding(maxBitrate: 2_500_000, maxFps: 5), simulcast: false // Simulcast is generally not recommended for screen shares ) // Publish the track to the room let publication = try await localParticipant.publish( videoTrack: screenTrack, options: publishOptions ) print("Screen share track published with SID: \(publication.sid)") ``` ``` -------------------------------- ### Create Screen Share Track with Options Source: https://github.com/livekit/client-sdk-swift/blob/main/_autodocs/api-reference/ScreenSharing.md Programmatically create a screen share video track, specifying capture options like FPS and dimensions. The track can then be started and published. ```swift let screenshare = try await LocalVideoTrack.createScreenShareTrack( options: ScreenShareCaptureOptions(fps: 5) ) try await screenshare.start() let publication = try await localParticipant.publish(videoTrack: screenshare) ``` -------------------------------- ### Publish Data with Error Handling Source: https://github.com/livekit/client-sdk-swift/blob/main/_autodocs/api-reference/DataStreams.md Publish binary data reliably with error handling. This example demonstrates how to catch and manage `LiveKitError` during data publishing. ```swift do { try await localParticipant.publish( data: data, options: DataPublishOptions(reliable: true) ) } catch let error as LiveKitError { switch error.type { case .invalidState: print("Not connected to room") case .invalidParameter: print("Invalid data parameters") default: print("Publishing failed: \(error.type)") } } ``` -------------------------------- ### Access AudioManager Singleton Source: https://github.com/livekit/client-sdk-swift/blob/main/_autodocs/api-reference/AudioManager.md Get the shared instance of AudioManager to manage audio settings. ```swift let audioManager = AudioManager.shared ``` -------------------------------- ### Observe Audio Engine Lifecycle Source: https://github.com/livekit/client-sdk-swift/blob/main/_autodocs/api-reference/AudioManager.md Implement and set custom observers to monitor the audio engine's start and stop events. This is useful for managing external audio resources or UI updates based on engine state. ```swift class MyAudioObserver: AudioEngineObserver { func audioEngineDidStart() { print("Audio engine started") } func audioEngineDidStop() { print("Audio engine stopped") } } AudioManager.shared.set(engineObservers: [MyAudioObserver()]) ``` -------------------------------- ### Publish Screen Share Track with Options Source: https://github.com/livekit/client-sdk-swift/blob/main/_autodocs/api-reference/ScreenSharing.md Create, start, and publish a screen share track with specific video encoding and publish options. Simulcast is typically disabled for screen shares. ```swift // Create and start track let screenTrack = try await LocalVideoTrack.createScreenShareTrack( options: ScreenShareCaptureOptions(fps: 5) ) try await screenTrack.start() // Publish with appropriate options let publishOptions = VideoPublishOptions( encoding: VideoEncoding(maxBitrate: 2_500_000, maxFps: 5), simulcast: false // No simulcast for screen share ) let publication = try await localParticipant.publish( videoTrack: screenTrack, options: publishOptions ) ``` -------------------------------- ### CallKit Integration: Audio Session Setup Source: https://github.com/livekit/client-sdk-swift/blob/main/_autodocs/api-reference/AudioManager.md Configure audio settings for CallKit integration by disabling automatic configuration, setting engine availability to none, and then re-enabling it with specific categories and modes when the CallKit session activates. ```swift // 1. Disable automatic configuration early AudioManager.shared.audioSession.isAutomaticConfigurationEnabled = false try AudioManager.shared.setEngineAvailability(.none) // 2. In your CXProviderDelegate func provider(_: CXProvider, didActivate session: AVAudioSession) { do { try session.setCategory(.playAndRecord, mode: .voiceChat, options: [.mixWithOthers]) try AudioManager.shared.setEngineAvailability(.default) } catch { // Error } } func provider(_: CXProvider, didDeactivate _: AVAudioSession) { do { try AudioManager.shared.setEngineAvailability(.none) } catch { // Error } } ``` -------------------------------- ### Publish Local Audio Track Source: https://github.com/livekit/client-sdk-swift/blob/main/_autodocs/api-reference/LocalParticipant.md Publishes a local audio track to the room. Ensure the audio track is created and started before publishing. Publishing options can be specified to control codec, bitrate, etc. ```swift let audioTrack = LocalAudioTrack.createTrack() try await audioTrack.start() let publication = try await localParticipant.publish(audioTrack: audioTrack) ``` -------------------------------- ### Adapt Video Quality Source: https://github.com/livekit/client-sdk-swift/blob/main/_autodocs/api-reference/TrackPublications.md Adapt video quality based on network conditions. Start with high quality and switch to medium or lower if bandwidth becomes limited. ```swift // Start with high quality try await videoPublication.setVideoQuality(.high) // Later, if bandwidth is limited try await videoPublication.setVideoQuality(.medium) ``` -------------------------------- ### Error Handling for Screen Share Initiation Source: https://github.com/livekit/client-sdk-swift/blob/main/_autodocs/api-reference/ScreenSharing.md Handles potential errors when attempting to start screen sharing, such as device access denial or invalid states. Provides specific feedback for different error types. ```swift do { try await localParticipant.setScreenShare(enabled: true) } catch let error as LiveKitError { switch error.type { case .deviceAccessDenied: print("Screen recording permission denied") case .invalidState: print("Cannot start screen share in current state") default: print("Screen share failed: \(error.type)") } } ``` -------------------------------- ### Manual AVAudioSession Configuration Source: https://github.com/livekit/client-sdk-swift/blob/main/_autodocs/api-reference/AudioManager.md Disable automatic audio session configuration and manually set the category, mode, and activate the session. This is useful for custom audio setups before starting microphone publishing. ```swift // Disable automatic configuration AudioManager.shared.audioSession.isAutomaticConfigurationEnabled = false // Manually configure before enabling mic let session = AVAudioSession.sharedInstance() try session.setCategory(.playAndRecord, mode: .voiceChat, options: [.defaultToSpeaker]) try session.setActive(true) ``` -------------------------------- ### prepare() Source: https://github.com/livekit/client-sdk-swift/blob/main/_autodocs/configuration.md Prepares the SDK for faster connection and publishing in a non-blocking manner. This should be called during app initialization. ```APIDOC ## prepare() ### Description Prepares the SDK for faster connection and publishing in a non-blocking manner. This should be called during app initialization. ### Method static func prepare() ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```swift // In app initialization LiveKitSDK.prepare() ``` ### Response None #### Success Response (200) None #### Response Example None ``` -------------------------------- ### Enable Microphone on App Launch Source: https://github.com/livekit/client-sdk-swift/blob/main/_autodocs/api-reference/AudioManager.md Prepare the SDK and enable the microphone for recording when the app launches. This involves calling `LiveKitSDK.prepare()` and setting recording to always prepared mode, followed by enabling the microphone during the room connection. ```swift // In App.init() or AppDelegate LiveKitSDK.prepare() try? await AudioManager.shared.setRecordingAlwaysPreparedMode(true) // In connect flow try await room.connect( url: url, token: token, connectOptions: ConnectOptions(enableMicrophone: true) ) ``` -------------------------------- ### Basic Room Usage Source: https://github.com/livekit/client-sdk-swift/blob/main/_autodocs/api-reference/Room.md Instantiate a Room, connect to a server, enable the local camera, and disconnect. Ensure you have a delegate conforming to RoomDelegate. ```swift let room = Room(delegate: self) try await room.connect(url: "ws://your_host", token: "your_jwt_token") try await room.localParticipant.setCamera(enabled: true) try await room.disconnect() ``` -------------------------------- ### List Available Simulators Source: https://github.com/livekit/client-sdk-swift/blob/main/AGENTS.md Lists all available simulators for platform-specific builds using `xcrun simctl list devices`. ```zsh # List available simulators for platform-specific builds xcrun simctl list devices ``` -------------------------------- ### Connect with Room Options Source: https://github.com/livekit/client-sdk-swift/blob/main/_autodocs/configuration.md Configure room connection settings like adaptive streaming, dynacast, background suspend, and default camera capture options. ```swift let roomOptions = RoomOptions( adaptiveStream: true, dynacast: true, suspendLocalVideoTracksInBackground: true, defaultCameraCaptureOptions: CameraCaptureOptions(targetResolution: .vga) ) try await room.connect( url: url, token: token, roomOptions: roomOptions ) ``` -------------------------------- ### Participant Name Property Source: https://github.com/livekit/client-sdk-swift/blob/main/_autodocs/api-reference/Participant.md Get the display name of the participant. This property is optional. ```swift public var name: String? ``` -------------------------------- ### Documentation File Structure Source: https://github.com/livekit/client-sdk-swift/blob/main/_autodocs/ABOUT.md This snippet shows the directory structure of the LiveKit Swift Client SDK documentation, outlining the purpose of each file. ```text output/ ├── README.md # Start here - overview and common tasks ├── INDEX.md # Complete index and navigation guide ├── ABOUT.md # This file ├── configuration.md # All option classes and configuration ├── types.md # All types and enumerations ├── errors.md # Error types and handling └── api-reference/ ├── Room.md # Room class documentation ├── Participant.md # Base Participant class ├── LocalParticipant.md # Local user APIs ├── RemoteParticipant.md # Remote user APIs ├── Tracks.md # Track classes ├── TrackPublications.md # Track publications ├── VideoView.md # Video rendering ├── AudioManager.md # Audio management ├── Delegates.md # Event protocols ├── DataStreams.md # Data and RPC ├── ScreenSharing.md # Screen capture └── Encryption.md # E2EE and encryption ``` -------------------------------- ### Build LiveKit SDK Benchmarks Source: https://github.com/livekit/client-sdk-swift/blob/main/AGENTS.md Builds the benchmarks for the LiveKit SDK. Navigate to the Benchmarks directory first. ```zsh # Build benchmarks cd Benchmarks && swiftly run +xcode swift build ``` -------------------------------- ### SpeechActivityEvent Enum Source: https://github.com/livekit/client-sdk-swift/blob/main/_autodocs/types.md Indicates speech activity events, specifically when speech starts or ends. ```swift public enum SpeechActivityEvent: String, Sendable { case speechStarted case speechEnded } ``` -------------------------------- ### Configure ICE Server Source: https://github.com/livekit/client-sdk-swift/blob/main/_autodocs/configuration.md Define STUN/TURN server configurations, including URLs, username, and credentials for authentication. ```swift let iceServer = IceServer( urls: ["turn:turnserver.example.com"], username: "user", credential: "password" ) let connectOptions = ConnectOptions(iceServers: [iceServer]) ``` -------------------------------- ### Check Participant Publish Permission Source: https://github.com/livekit/client-sdk-swift/blob/main/_autodocs/types.md Example of checking if a participant has the permission to publish using the ParticipantPermissions struct. ```swift if participant.permissions.contains(.canPublish) { print("Participant can publish") } ``` -------------------------------- ### Configure Room for Low Bandwidth Scenarios Source: https://github.com/livekit/client-sdk-swift/blob/main/_autodocs/README.md Set up RoomOptions with adaptiveStream and dynacast enabled, along with ConnectOptions for connection behavior. This optimizes for limited bandwidth. ```swift let connectOptions = ConnectOptions( reconnectAttempts: 5, reconnectAttemptDelay: 0.5 ) let roomOptions = RoomOptions( adaptiveStream: true, dynacast: true ) try await room.connect( url: url, token: token, connectOptions: connectOptions, roomOptions: roomOptions ) ``` -------------------------------- ### Check Room Connection State Source: https://github.com/livekit/client-sdk-swift/blob/main/_autodocs/types.md Example of how to check if a room is currently connected using the ConnectionState enum. ```swift if room.connectionState == .connected { print("Room is connected") } ``` -------------------------------- ### ConnectOptions Constructor Source: https://github.com/livekit/client-sdk-swift/blob/main/_autodocs/configuration.md Defines the available parameters for establishing a room connection. These options control aspects like reconnection behavior, timeouts, and ICE server configurations. ```swift public init(autoSubscribe: Bool = true, reconnectAttempts: Int = 10, reconnectAttemptDelay: TimeInterval = .defaultReconnectDelay, reconnectMaxDelay: TimeInterval = .defaultReconnectMaxDelay, socketConnectTimeoutInterval: TimeInterval = .defaultSocketConnect, primaryTransportConnectTimeout: TimeInterval = .defaultTransportState, publisherTransportConnectTimeout: TimeInterval = .defaultTransportState, iceServers: [IceServer] = [], iceTransportPolicy: IceTransportPolicy = .all, isDscpEnabled: Bool = false, enableMicrophone: Bool = false, protocolVersion: ProtocolVersion = .v16, clientProtocol: ClientProtocol = .v1) ``` -------------------------------- ### Assigning Video Track Source: https://github.com/livekit/client-sdk-swift/blob/main/_autodocs/api-reference/VideoView.md Assign a VideoTrack to the VideoView to start rendering. Set to nil to stop rendering. ```swift videoView.track = remoteVideoTrack // Starts rendering videoView.track = nil // Stops rendering ``` -------------------------------- ### connect(url:token:connectOptions:roomOptions:) Source: https://github.com/livekit/client-sdk-swift/blob/main/_autodocs/api-reference/Room.md Establishes a connection to a LiveKit server. This method handles the WebSocket connection and authentication using a JWT token. ```APIDOC ## connect(url:token:connectOptions:roomOptions:) ### Description Establishes a connection to a LiveKit server. This method handles the WebSocket connection and authentication using a JWT token. ### Method `public func connect(url urlString: String, token: String, connectOptions: ConnectOptions? = nil, roomOptions: RoomOptions? = nil) async throws` ### Parameters #### Path Parameters * None #### Query Parameters * None #### Request Body * None ### Parameters * **urlString** (String) - Required - WebSocket URL of the LiveKit server (ws:// or wss://) * **token** (String) - Required - JWT token for authentication, generated by LiveKit server * **connectOptions** (ConnectOptions?) - Optional - Options for connection behavior (reconnection, timeouts, etc.) * **roomOptions** (RoomOptions?) - Optional - Options for room behavior (capture defaults, E2EE, etc.) ### Request Example ```swift let connectOptions = ConnectOptions(autoSubscribe: true, reconnectAttempts: 5) let roomOptions = RoomOptions(adaptiveStream: true, dynacast: true) try await room.connect( url: "wss://livekit.example.com", token: jwtToken, connectOptions: connectOptions, roomOptions: roomOptions ) ``` ### Response #### Success Response (200) Void (async) #### Response Example None ### Throws `LiveKitError` with types including `.failedToParseUrl`, `.network`, `.joinFailure`, `.roomDeleted`, etc. ``` -------------------------------- ### Prepare SDK for Faster Connection Source: https://github.com/livekit/client-sdk-swift/blob/main/_autodocs/configuration.md Prepares the SDK for faster connection and publishing. This is a non-blocking operation and should be called during app initialization. ```swift public static func prepare() ``` ```swift // In app initialization LiveKitSDK.prepare() ``` -------------------------------- ### Subscribe to Remote Track Source: https://github.com/livekit/client-sdk-swift/blob/main/_autodocs/api-reference/TrackPublications.md Subscribe to a remote track to start receiving its media. The track object will be populated after a successful subscription. ```swift try await remotePublication.subscribe() // Track will be populated after successful subscription if let videoTrack = remotePublication.videoTrack { videoView.track = videoTrack } ``` -------------------------------- ### Participant Client Protocol Property Source: https://github.com/livekit/client-sdk-swift/blob/main/_autodocs/api-reference/Participant.md Get the protocol version announced by the participant's client. This property is of type `ClientProtocol`. ```swift public var clientProtocol: ClientProtocol ``` -------------------------------- ### Implement RPC for Client-Server Communication Source: https://github.com/livekit/client-sdk-swift/blob/main/_autodocs/README.md Demonstrates making a remote procedure call (RPC) from a client to a server and handling the RPC on the server side. Useful for custom commands. ```swift // Client: Call method on remote participant let request = try JSONEncoder().encode(["query": "What is the weather?"]) let responseData = try await localParticipant.rpc( method: "askWeather", to: agentIdentity, data: request ) let response = try JSONDecoder().decode(WeatherResponse.self, from: responseData) // Server: Handle RPC call class AgentHandler: NextInvokable { func invoke(with request: RpcInvocationData) async throws -> RpcInvocationData? { let query = try JSONDecoder().decode( WeatherQuery.self, from: request.data ) let weather = getWeather(for: query.query) let response = WeatherResponse(weather: weather) return RpcInvocationData( method: request.method, data: try JSONEncoder().encode(response), requestId: request.requestId ) } } ``` -------------------------------- ### Initialize LiveKit SDK Source: https://github.com/livekit/client-sdk-swift/blob/main/_autodocs/README.md Prepare the LiveKit SDK during app initialization by setting the log level and calling the non-blocking prepare() method. This ensures the SDK is ready for use. ```swift // In App initialization (AppDelegate/App.init()) LiveKitSDK.setLogLevel(.info) LiveKitSDK.prepare() // Non-blocking prep ``` -------------------------------- ### Automatic Screen Share Detection Source: https://github.com/livekit/client-sdk-swift/blob/main/_autodocs/api-reference/ScreenSharing.md Listens for room events to detect when screen sharing starts or stops. This is useful for updating UI or logging. ```swift extension MyViewController: RoomDelegate { func room(_: Room, participant: LocalParticipant, didPublishTrack publication: LocalTrackPublication) { if publication.source == .screenShare { print("Screen sharing started") } } func room(_: Room, participant: LocalParticipant, didUnpublishTrack publication: LocalTrackPublication) { if publication.source == .screenShare { print("Screen sharing stopped") } } } ``` -------------------------------- ### Create Audio Track with Capture Options Source: https://github.com/livekit/client-sdk-swift/blob/main/_autodocs/configuration.md Configure audio capture settings like echo cancellation and noise suppression when creating a local audio track. ```swift let audioOptions = AudioCaptureOptions( echoCancellation: true, noiseSuppression: true ) let audioTrack = LocalAudioTrack.createTrack(options: audioOptions) ``` -------------------------------- ### Run LiveKit SDK Benchmarks Source: https://github.com/livekit/client-sdk-swift/blob/main/AGENTS.md Runs the benchmarks for the LiveKit SDK. Requires a local LiveKit server. Set the `LK_BENCHMARK` environment variable. ```zsh # Run benchmarks (requires local server: livekit-server --dev) cd Benchmarks && LK_BENCHMARK=1 swiftly run +xcode swift package --disable-sandbox benchmark ``` -------------------------------- ### Handle Speaking Status Change Source: https://github.com/livekit/client-sdk-swift/blob/main/_autodocs/api-reference/Delegates.md Called when a participant starts or stops speaking. Useful for UI updates like highlighting active speakers. ```swift func room(_: Room, participant: Participant, isSpeaking: Bool) { if isSpeaking { print("\(participant.name ?? "User") started speaking") } } ``` -------------------------------- ### Participant Connection Quality Property Source: https://github.com/livekit/client-sdk-swift/blob/main/_autodocs/api-reference/Participant.md Get the assessed network connection quality for the participant, indicated by values like `.excellent`, `.good`, or `.poor`. ```swift public var connectionQuality: ConnectionQuality ``` -------------------------------- ### Participant Audio Level Property Source: https://github.com/livekit/client-sdk-swift/blob/main/_autodocs/api-reference/Participant.md Get the current audio level of the participant, ranging from 0.0 to 1.0, based on recent audio frames. ```swift public var audioLevel: Float ``` -------------------------------- ### RoomOptions Constructor Source: https://github.com/livekit/client-sdk-swift/blob/main/_autodocs/configuration.md Defines the available parameters for room behavior and media defaults. These options allow customization of capture, publishing, and encryption settings. ```swift public init(defaultCameraCaptureOptions: CameraCaptureOptions = CameraCaptureOptions(), defaultScreenShareCaptureOptions: ScreenShareCaptureOptions = ScreenShareCaptureOptions(), defaultAudioCaptureOptions: AudioCaptureOptions = AudioCaptureOptions(), defaultVideoPublishOptions: VideoPublishOptions = VideoPublishOptions(), defaultAudioPublishOptions: AudioPublishOptions = AudioPublishOptions(), defaultDataPublishOptions: DataPublishOptions = DataPublishOptions(), adaptiveStream: Bool = false, dynacast: Bool = false, stopLocalTrackOnUnpublish: Bool = true, suspendLocalVideoTracksInBackground: Bool = true, e2eeOptions: E2EEOptions? = nil, encryptionOptions: EncryptionOptions? = nil, reportRemoteTrackStatistics: Bool = false, singlePeerConnection: Bool = false) ``` -------------------------------- ### Create Camera Track with Capture Options Source: https://github.com/livekit/client-sdk-swift/blob/main/_autodocs/configuration.md Configure camera capture settings such as dimensions and frames per second when creating a local video track. ```swift let cameraOptions = CameraCaptureOptions( dimensions: Dimensions(width: 1280, height: 720), fps: 30 ) let videoTrack = try await LocalVideoTrack.createCameraTrack( options: cameraOptions ) ``` -------------------------------- ### Room Initialization Source: https://github.com/livekit/client-sdk-swift/blob/main/_autodocs/api-reference/Room.md Creates a new Room instance. The Room must be connected via the connect method before it can be used. ```APIDOC ## Room Initialization ### Description Creates a new `Room` instance. The `Room` must be connected via the `connect(url:token:connectOptions:roomOptions:)` method before it can be used. ### Method `public init()` ``` -------------------------------- ### Publish Data to Specific Participant Source: https://github.com/livekit/client-sdk-swift/blob/main/_autodocs/api-reference/DataStreams.md Example of publishing data to a specific remote participant using DataPublishOptions. Sets reliable delivery and a topic for the message. ```swift let options = DataPublishOptions( reliable: true, destinationIdentities: [remoteParticipant.identity!], topic: "direct-message" ) try await localParticipant.publish(data: data, options: options) ``` -------------------------------- ### Create and Connect to Room with E2EE Source: https://github.com/livekit/client-sdk-swift/blob/main/_autodocs/api-reference/Encryption.md Instantiate E2EEOptions and RoomOptions to connect to a room with end-to-end encryption enabled. ```swift let e2eeOptions = E2EEOptions(keyProvider: MyKeyProvider()) let roomOptions = RoomOptions(e2eeOptions: e2eeOptions) try await room.connect( url: url, token: token, roomOptions: roomOptions ) ``` -------------------------------- ### Publish Audio Track with Publish Options Source: https://github.com/livekit/client-sdk-swift/blob/main/_autodocs/configuration.md Configure audio track publishing settings, specifically the maximum bitrate. ```swift let publishOptions = AudioPublishOptions( encoding: AudioEncoding(maxBitrate: 128_000) ) let publication = try await localParticipant.publish( audioTrack: audioTrack, options: publishOptions ) ``` -------------------------------- ### Enable Camera Publishing Source: https://github.com/livekit/client-sdk-swift/blob/main/_autodocs/api-reference/LocalParticipant.md Convenience method to enable camera publishing. Creates a camera track if one does not already exist. ```swift try await localParticipant.setCamera(enabled: true) ``` -------------------------------- ### Manual Subscription Control Source: https://github.com/livekit/client-sdk-swift/blob/main/_autodocs/api-reference/TrackPublications.md Manually control track subscriptions by setting autoSubscribe to false in ConnectOptions. Subscribe to specific tracks later when needed, for example, when a user selects a participant to watch. ```swift // In your room setup let connectOptions = ConnectOptions(autoSubscribe: false) try await room.connect(url: url, token: token, connectOptions: connectOptions) // Later, when the user selects a participant to watch if let videoPublication = selectedParticipant.videoTracks.first as? RemoteTrackPublication { try await videoPublication.subscribe() if let videoTrack = videoPublication.videoTrack { videoView.track = videoTrack } } ``` -------------------------------- ### Connect to Room and Publish Tracks Source: https://github.com/livekit/client-sdk-swift/blob/main/README.md Connects to a LiveKit room and enables the camera and microphone for publishing. Ensure you have valid URL and token. ```swift import LiveKit import UIKit class RoomViewController: UIViewController { lazy var room = Room(delegate: self) lazy var remoteVideoView: VideoView = { let videoView = VideoView() view.addSubview(videoView) // Additional initialization ... return videoView }() lazy var localVideoView: VideoView = { let videoView = VideoView() view.addSubview(videoView) // Additional initialization ... return videoView }() override func viewDidLoad() { super.viewDidLoad() view.backgroundColor = .white let url = "ws://your_host" let token = "your_jwt_token" Task { do { try await room.connect(url: url, token: token) // Connection successful... // Publishing camera & mic... try await room.localParticipant.setCamera(enabled: true) try await room.localParticipant.setMicrophone(enabled: true) } catch { // Failed to connect } } } } extension RoomViewController: RoomDelegate { func room(_: Room, participant _: LocalParticipant, didPublishTrack publication: LocalTrackPublication) { guard let track = publication.track as? VideoTrack else { return } DispatchQueue.main.async { self.localVideoView.track = track } } func room(_: Room, participant _: RemoteParticipant, didSubscribeTrack publication: RemoteTrackPublication) { guard let track = publication.track as? VideoTrack else { return } DispatchQueue.main.async { self.remoteVideoView.track = track } } } ``` -------------------------------- ### RemoteTrackPublication Subscription Management Source: https://github.com/livekit/client-sdk-swift/blob/main/_autodocs/api-reference/TrackPublications.md Provides methods for managing subscriptions to remote tracks, including subscribing, unsubscribing, and a convenience method to set the subscription state. Examples demonstrate usage for both subscribing and unsubscribing. ```APIDOC ### Subscription Management #### subscribe() ```swift public func subscribe() async throws ``` Subscribes to this remote track (requests the server to start sending). **Throws:** `LiveKitError` if subscription fails **Example:** ```swift try await remotePublication.subscribe() // Track will be populated after successful subscription if let videoTrack = remotePublication.videoTrack { videoView.track = videoTrack } ``` #### unsubscribe() ```swift public func unsubscribe() async throws ``` Unsubscribes from this remote track (stops receiving). **Throws:** `LiveKitError` **Example:** ```swift try await remotePublication.unsubscribe() videoView.track = nil ``` #### setSubscribed(_:) ```swift public func setSubscribed(_ subscribed: Bool) async throws ``` Convenience method to subscribe or unsubscribe. **Example:** ```swift try await remotePublication.setSubscribed(true) // Subscribe try await remotePublication.setSubscribed(false) // Unsubscribe ``` ``` -------------------------------- ### Enable Microphone Publishing Source: https://github.com/livekit/client-sdk-swift/blob/main/_autodocs/api-reference/LocalParticipant.md Convenience method to enable microphone publishing. Creates an audio track if one does not already exist. ```swift try await localParticipant.setMicrophone(enabled: true) ``` -------------------------------- ### Connect to Room with Data Channel Encryption Source: https://github.com/livekit/client-sdk-swift/blob/main/_autodocs/api-reference/Encryption.md Set up and connect to a room using EncryptionOptions for data channel encryption. ```swift let encryptionOptions = EncryptionOptions( keyProvider: MyEncryptionKeyProvider() ) let roomOptions = RoomOptions(encryptionOptions: encryptionOptions) try await room.connect( url: url, token: token, roomOptions: roomOptions ) ``` -------------------------------- ### Connect to LiveKit Server Source: https://github.com/livekit/client-sdk-swift/blob/main/_autodocs/api-reference/Room.md Establishes a connection to a LiveKit server with custom connection and room options. Ensure the JWT token is valid and the URL is correct. ```swift let connectOptions = ConnectOptions(autoSubscribe: true, reconnectAttempts: 5) let roomOptions = RoomOptions(adaptiveStream: true, dynacast: true) try await room.connect( url: "wss://livekit.example.com", token: jwtToken, connectOptions: connectOptions, roomOptions: roomOptions ) ``` -------------------------------- ### Publish Video Track with Publish Options Source: https://github.com/livekit/client-sdk-swift/blob/main/_autodocs/configuration.md Configure video track publishing settings, including encoding, simulcast, and fallback codecs. ```swift let publishOptions = VideoPublishOptions( encoding: VideoEncoding(maxBitrate: 2_500_000, maxFps: 30), simulcast: true ) let publication = try await localParticipant.publish( videoTrack: videoTrack, options: publishOptions ) ``` -------------------------------- ### RemoteTrackPublication Video Quality Control Source: https://github.com/livekit/client-sdk-swift/blob/main/_autodocs/api-reference/TrackPublications.md Details methods for controlling the quality and frame rate of remote video tracks. Users can request specific video qualities (low, medium, high) and frame rates, with examples provided for each. ```APIDOC ### Video Quality Control #### setVideoQuality(_:) ```swift public func setVideoQuality(_ quality: VideoQuality) async throws ``` Request a specific video quality for this track. | Quality | Description | |---------|-------------| | `.low` | Low resolution (360p or lower) | | `.medium` | Medium resolution (720p) | | `.high` | High resolution (1080p+) | **Throws:** `LiveKitError` if quality change fails **Example:** ```swift try await remotePublication.setVideoQuality(.high) ``` #### setVideoFps(_:) ```swift public func setVideoFps(_ fps: UInt) async throws ``` Request a specific frame rate. **Example:** ```swift try await remotePublication.setVideoFps(30) // Request 30 FPS ``` ``` -------------------------------- ### Recommended Screen Share Publish Options Source: https://github.com/livekit/client-sdk-swift/blob/main/_autodocs/api-reference/ScreenSharing.md Configures video publishing options for screen sharing, optimizing for lower bandwidth and FPS. This includes setting a maximum bitrate and FPS, and disabling simulcast. ```swift let screenOptions = ScreenShareCaptureOptions(fps: 5) let publishOptions = VideoPublishOptions( encoding: VideoEncoding(maxBitrate: 2_500_000, maxFps: 5), simulcast: false ) ``` -------------------------------- ### Disable SDK Audio Engine and Session Configuration for CallKit Source: https://github.com/livekit/client-sdk-swift/blob/main/README.md Disable the SDK's automatic AVAudioSession configuration and prevent the audio engine from starting outside CallKit's activation window. This should be done as early as possible, before connecting to a Room. ```swift AudioManager.shared.audioSession.isAutomaticConfigurationEnabled = false try AudioManager.shared.setEngineAvailability(.none) ``` -------------------------------- ### Create Screen Share Track (macOS) Source: https://github.com/livekit/client-sdk-swift/blob/main/_autodocs/api-reference/ScreenSharing.md How to create a `LocalVideoTrack` for screen sharing on macOS. ```APIDOC ## Create Screen Share Track (macOS) ### Description This method creates a `LocalVideoTrack` specifically for capturing and broadcasting the user's screen content on macOS. ### Method Signature ```swift public static func createScreenShareTrack( name: String = Track.screenShareName, options: ScreenShareCaptureOptions? = nil, reportStatistics: Bool = false ) -> LocalVideoTrack ``` ### Parameters - **`name`** (String, Optional): The name of the track. Defaults to "Screen Share". - **`options`** (`ScreenShareCaptureOptions?`, Optional): Configuration options for screen capture, such as resolution and FPS. If `nil`, default options are used. - **`reportStatistics`** (Bool, Optional): If `true`, statistics will be collected for this track. Defaults to `false`. ### Returns A `LocalVideoTrack` instance configured for screen sharing. ### Example ```swift // Create a screen share track with default options let screenshareTrack = try await LocalVideoTrack.createScreenShareTrack() // Publish the track try await localParticipant.publish(videoTrack: screenshareTrack) ``` ### Configuration Example ```swift let options = ScreenShareCaptureOptions( dimensions: Dimensions(width: 1920, height: 1080), fps: 5 ) let screenshareTrackWithOptions = try await LocalVideoTrack.createScreenShareTrack(options: options) ``` ``` -------------------------------- ### Lifecycle Source: https://github.com/livekit/client-sdk-swift/blob/main/_autodocs/api-reference/RemoteParticipant.md Understand the lifecycle of a remote participant within a room, from joining to leaving. ```APIDOC ## Lifecycle ### Description Understand the lifecycle of a remote participant within a room, from joining to leaving. ### Stages 1. **Join** - Remote participant enters room - `RoomDelegate.room(_:participantDidJoin:)` fires 2. **Publish Tracks** - Remote publishes media - `RoomDelegate.room(_:participant:didSubscribeTrack:)` fires 3. **Active** - Participant fully connected - `participant.state == .active` 4. **Leave** - Participant disconnects - `RoomDelegate.room(_:participantDidLeave:)` fires - `participant.state == .disconnected` ``` -------------------------------- ### Publishing Video Track with Options Source: https://github.com/livekit/client-sdk-swift/blob/main/_autodocs/README.md Create and publish a camera video track with specific capture options and encoding settings, including simulcast. ```swift // Camera with 30 FPS and 2.5 Mbps let cameraOptions = CameraCaptureOptions(fps: 30) let videoTrack = try await LocalVideoTrack.createCameraTrack(options: cameraOptions) let publishOptions = VideoPublishOptions( encoding: VideoEncoding(maxBitrate: 2_500_000, maxFps: 30), simulcast: true ) let publication = try await localParticipant.publish( videoTrack: videoTrack, options: publishOptions ) ``` -------------------------------- ### Audio Session Configuration Source: https://github.com/livekit/client-sdk-swift/blob/main/_autodocs/api-reference/AudioManager.md Configure audio session settings, including automatic configuration. ```APIDOC ## Audio Session Configuration ### audioSession ```swift public let audioSession: AudioSessionConfiguration ``` Configuration wrapper for `AVAudioSession`. ### isAutomaticConfigurationEnabled ```swift public var isAutomaticConfigurationEnabled: Bool ``` Whether the SDK automatically configures the audio session. Enabled by default. **Example - Manual Configuration:** ```swift // Disable automatic configuration AudioManager.shared.audioSession.isAutomaticConfigurationEnabled = false // Manually configure before enabling mic let session = AVAudioSession.sharedInstance() try session.setCategory(.playAndRecord, mode: .voiceChat, options: [.defaultToSpeaker]) try session.setActive(true) ``` ``` -------------------------------- ### AudioManager Singleton Source: https://github.com/livekit/client-sdk-swift/blob/main/_autodocs/api-reference/AudioManager.md Access the global singleton instance of AudioManager for managing audio. ```APIDOC ## AudioManager Singleton ### shared ```swift public static let shared: AudioManager ``` Global singleton instance for audio management. ``` -------------------------------- ### Import LiveKit SDK Source: https://github.com/livekit/client-sdk-swift/blob/main/_autodocs/api-reference/Participant.md Import the LiveKit SDK to access its functionalities. This is a prerequisite for using any LiveKit classes or methods. ```swift import LiveKit ``` -------------------------------- ### Enable Screen Sharing Source: https://github.com/livekit/client-sdk-swift/blob/main/_autodocs/api-reference/LocalParticipant.md Convenience method to enable screen sharing. Creates a screen share track if one does not already exist. ```swift try await localParticipant.setScreenShare(enabled: true) ``` -------------------------------- ### Enable Always-Prepared Recording Mode Source: https://github.com/livekit/client-sdk-swift/blob/main/Docs/audio.md Pre-warms the audio engine to minimize microphone publish latency. This mode keeps the audio engine running in a muted state even across room disconnections. ```swift Task.detached { try? await AudioManager.shared.setRecordingAlwaysPreparedMode(true) } ``` -------------------------------- ### publish(data:options:) Source: https://github.com/livekit/client-sdk-swift/blob/main/_autodocs/api-reference/DataStreams.md Publishes arbitrary binary data to other participants in the room. Supports options for reliability, specific recipients, and topics. ```APIDOC ## publish(data:options:) ### Description Publishes arbitrary binary data to other participants in the room. ### Method `async throws` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body * **data** (Data) - Required - Binary data (max 15KB) * **options** (DataPublishOptions?) - Optional - Publishing options ### Throws `LiveKitError` if publishing fails ### Example ```swift let messageData = "Hello, room!".data(using: .utf8)! try await localParticipant.publish( data: messageData, options: DataPublishOptions(reliable: true, topic: "chat") ) ``` ```