The ConnectionState enum represents the current connection state of a LiveKit room.
Cases
The room is disconnected and not attempting to connect.This is the initial state before connecting and the final state after disconnecting.
The room is currently attempting to establish a connection.This state occurs during the initial connection attempt.
The room was previously connected but is now attempting to reconnect.This state occurs when the connection is lost and the SDK is trying to restore it.
The room is successfully connected.In this state, you can publish and subscribe to tracks, send data, etc.
The room is in the process of disconnecting.This is a transitional state before reaching disconnected.
Usage
Monitor connection state changes through the RoomDelegate:
func room(_ room: Room, didUpdateConnectionState connectionState: ConnectionState, from oldConnectionState: ConnectionState) {
switch connectionState {
case .disconnected:
print("Disconnected from room")
updateUI(connected: false)
case .connecting:
print("Connecting to room...")
showLoadingIndicator()
case .reconnecting:
print("Reconnecting to room...")
showReconnectingIndicator()
case .connected:
print("Connected to room")
updateUI(connected: true)
hideLoadingIndicator()
case .disconnecting:
print("Disconnecting from room...")
showLoadingIndicator()
}
}
State Transitions
Typical state transition flow:
disconnected → connecting → connected
↓
(on error)
↓
disconnected
Reconnection flow:
connected → reconnecting → connected
↓
(max attempts)
↓
disconnected
Manual disconnect:
connected → disconnecting → disconnected
Checking Connection State
You can check the current connection state at any time:
let room = Room()
if room.connectionState == .connected {
// Room is connected, safe to publish tracks
try await room.localParticipant.publish(videoTrack: track)
}
Example with SwiftUI
import SwiftUI
import LiveKit
struct RoomView: View {
@StateObject var viewModel: RoomViewModel
var body: some View {
VStack {
statusView
// Rest of your UI
}
}
@ViewBuilder
var statusView: some View {
switch viewModel.connectionState {
case .disconnected:
Text("Disconnected")
.foregroundColor(.red)
case .connecting:
HStack {
ProgressView()
Text("Connecting...")
}
case .reconnecting:
HStack {
ProgressView()
Text("Reconnecting...")
}
.foregroundColor(.orange)
case .connected:
Text("Connected")
.foregroundColor(.green)
case .disconnecting:
HStack {
ProgressView()
Text("Disconnecting...")
}
}
}
}
class RoomViewModel: ObservableObject, RoomDelegate {
@Published var connectionState: ConnectionState = .disconnected
let room = Room()
init() {
room.add(delegate: self)
}
func room(_ room: Room, didUpdateConnectionState connectionState: ConnectionState, from oldConnectionState: ConnectionState) {
DispatchQueue.main.async {
self.connectionState = connectionState
}
}
}
ReconnectMode
The SDK supports two reconnection modes:
Quick reconnection mode attempts to maintain the same session, reusing existing transport connections and published tracks.This is faster but may not succeed in all network conditions.
Full reconnection mode performs a complete new connection to the LiveKit server, closing existing connections and re-publishing all tracks.This is slower but more reliable for recovering from severe connection issues.
Monitoring Reconnect Mode
func room(_ room: Room, didStartReconnectWithMode reconnectMode: ReconnectMode) {
switch reconnectMode {
case .quick:
print("Starting quick reconnection")
case .full:
print("Starting full reconnection")
}
}
func room(_ room: Room, didCompleteReconnectWithMode reconnectMode: ReconnectMode) {
print("Reconnection completed using \(reconnectMode) mode")
}