The Room class is the main entry point for connecting to a LiveKit server. It manages the connection state, participants, tracks, and provides delegate callbacks for room events.
Creating a Room
Create a Room instance with optional configuration:
let room = Room(
delegate: self,
connectOptions: ConnectOptions(),
roomOptions: RoomOptions()
)
Room Options
Configure room behavior with RoomOptions:
let roomOptions = RoomOptions(
defaultCameraCaptureOptions: CameraCaptureOptions(),
defaultAudioCaptureOptions: AudioCaptureOptions(),
defaultVideoPublishOptions: VideoPublishOptions(),
defaultAudioPublishOptions: AudioPublishOptions(),
adaptiveStream: true,
reportRemoteTrackStatistics: true,
suspendLocalVideoTracksInBackground: true
)
Connecting to a Room
Connect to a LiveKit room using a URL and token:
try await room.connect(
url: "wss://your-livekit-server.com",
token: "your-jwt-token"
)
The connect method is asynchronous and throws errors if connection fails. Always wrap it in a do-catch block or handle errors appropriately.
Connection Options
You can specify ConnectOptions to control connection behavior:
let connectOptions = ConnectOptions(
enableMicrophone: true // Auto-publish microphone on connect
)
try await room.connect(
url: "wss://your-livekit-server.com",
token: "your-jwt-token",
connectOptions: connectOptions
)
Connection Lifecycle
The room connection goes through several states defined by ConnectionState:
disconnected - Not connected to the room
connecting - Attempting to connect
connected - Successfully connected
reconnecting - Connection lost, attempting to reconnect
disconnecting - Disconnecting from the room
Monitor connection state changes:
class MyViewController: RoomDelegate {
func room(_ room: Room, didUpdate connectionState: ConnectionState, oldValue: ConnectionState) {
switch connectionState {
case .connected:
print("Connected to room")
case .reconnecting:
print("Connection lost, reconnecting...")
case .disconnected:
print("Disconnected from room")
default:
break
}
}
}
The SDK automatically handles reconnection when the connection is lost. It will attempt to restore the session and re-establish track subscriptions.
Room Properties
Access room information and participants:
// Room metadata
room.sid // Server-assigned room ID
room.name // Room name
room.metadata // Room metadata
room.serverVersion // LiveKit server version
room.serverRegion // Server region code
// Connection info
room.connectionState // Current connection state
room.url // User-provided URL
room.connectedUrl // Actual connected URL (may include region)
// Participants
room.localParticipant // Local participant
room.remoteParticipants // Dictionary of remote participants [Identity: RemoteParticipant]
room.activeSpeakers // Array of currently speaking participants
// Room statistics
room.participantCount // Total number of participants
room.publishersCount // Number of publishing participants
room.maxParticipants // Maximum allowed participants
room.isRecording // Whether room is being recorded
Disconnecting
Disconnect from the room:
The disconnect process:
- Sends a leave message to the server
- Stops all local tracks
- Cleans up remote participants and tracks
- Resets connection state to
disconnected
Always call disconnect() when leaving a room to properly clean up resources and notify the server.
Room Events
Implement the RoomDelegate protocol to receive room events:
@objc protocol RoomDelegate {
// Connection events
optional func room(_ room: Room, didUpdate connectionState: ConnectionState, oldValue: ConnectionState)
// Participant events
optional func room(_ room: Room, participantDidJoin participant: RemoteParticipant)
optional func room(_ room: Room, participantDidDisconnect participant: RemoteParticipant)
// Track publication events
optional func room(_ room: Room, participant: Participant, didPublishTrack publication: TrackPublication)
optional func room(_ room: Room, participant: Participant, didUnpublishTrack publication: TrackPublication)
// Track subscription events (remote tracks only)
optional func room(_ room: Room, participant: RemoteParticipant, didSubscribeTrack publication: RemoteTrackPublication)
optional func room(_ room: Room, participant: RemoteParticipant, didUnsubscribeTrack publication: RemoteTrackPublication)
// Data events
optional func room(_ room: Room, participant: RemoteParticipant?, didReceiveData data: Data, topic: String?)
// Metadata events
optional func room(_ room: Room, didUpdateMetadata metadata: String)
optional func room(_ room: Room, participant: Participant, didUpdateMetadata metadata: String)
// Recording events
optional func room(_ room: Room, didUpdateIsRecording isRecording: Bool)
}
Example Implementation
class RoomManager: RoomDelegate {
let room = Room()
init() {
room.delegates.add(delegate: self)
}
func room(_ room: Room, participantDidJoin participant: RemoteParticipant) {
print("Participant joined: \(participant.identity ?? "unknown")")
participant.delegates.add(delegate: self)
}
func room(_ room: Room, participant: RemoteParticipant, didSubscribeTrack publication: RemoteTrackPublication) {
print("Subscribed to track: \(publication.name)")
if let videoTrack = publication.track as? VideoTrack {
// Attach to video view
videoTrack.add(videoRenderer: videoView)
}
}
func room(_ room: Room, participant: RemoteParticipant?, didReceiveData data: Data, topic: String?) {
print("Received data on topic: \(topic ?? "default")")
}
}
MulticastDelegate
The Room uses MulticastDelegate to support multiple delegates:
// Add a delegate
room.delegates.add(delegate: myDelegate)
// Remove a delegate
room.delegates.remove(delegate: myDelegate)
This allows multiple components to observe room events simultaneously.
SwiftUI Integration
The Room conforms to ObservableObject for SwiftUI integration:
struct RoomView: View {
@StateObject var room = Room()
var body: some View {
VStack {
Text("Connection: \(room.connectionState)")
Text("Participants: \(room.participantCount)")
ForEach(Array(room.remoteParticipants.values)) { participant in
ParticipantView(participant: participant)
}
}
.task {
try? await room.connect(url: url, token: token)
}
}
}
Best Practices
- Always handle connection errors: Wrap
connect() in try-catch blocks
- Disconnect when done: Call
disconnect() to clean up resources
- Monitor connection state: Handle reconnection scenarios gracefully
- Use delegates: Add room and participant delegates early to avoid missing events
- Check permissions: Verify participant permissions before attempting operations