The iOS SDK ships as a Swift Package, mirroring the @levelchat/web API one-to-one — same class names, method names, event names, and error codes — adapted to Swift Concurrency (async/await, actor, AsyncSequence).
3,108 LOC of Swift, 21 XCTest cases passing, MIT-licensed. Real WebRTC via stasel/WebRTC.
Install
Swift Package Manager (preferred)
// Package.swift
dependencies: [
.package(url: "https://github.com/levelchat/levelchat.git", from: "0.1.0"),
],
targets: [
.target(
name: "MyApp",
dependencies: [
.product(name: "LevelChat", package: "levelchat"),
]
),
],CocoaPods
pod 'LevelChat', '~> 0.1.0'Permissions
Add to Info.plist:
<key>NSCameraUsageDescription</key>
<string>Used for video calls</string>
<key>NSMicrophoneUsageDescription</key>
<string>Used for voice + video calls</string>For screen sharing, also add a Broadcast Extension target — see the example app under packages/sdk-ios/Example/.
Quickstart
import LevelChat
// In production the token comes from YOUR BACKEND. Never ship an
// apiKey in the binary — your auth-svc + room-token issuance flow
// mints short-lived JWTs scoped to a single (room, user, role).
let token = try await fetchTokenFromYourBackend()
let client = try await LevelChat(config: LevelChatConfig(
region: "eu-fsn",
logLevel: .info
))
let room = try await client.joinRoom(JoinRoomOptions(token: token))
// Subscribe to events as an AsyncSequence — Swift's idiomatic way
// to stream a typed event bus.
for await event in await room.events {
switch event {
case .participantJoined(let p): print("joined: \(p.identity)")
case .trackPublished(let t): print("track: \(t.id) \(t.kind)")
default: break
}
}Public API
actor LevelChat— the entrypoint; one instance per process.actor Room— state machine,connect / leave / publish / subscribe.AsyncStream<RoomEvent>— typed event surface (participantJoined,trackPublished,qualityChanged, …).Combinebridge —room.eventsPublisher: AnyPublisher<RoomEvent, Never>for SwiftUI integration.
Modules: Errors, Logger, Events, Constants, Region, Quality, Encryption, Devices, Signaling, Peer, Track, Publication, Subscription, Participant, Room, AudioSession, Lifecycle, ScreenShare.
Audio session
Auto-configured for voice calls — AVAudioSession.playAndRecord + .voiceChat + .allowBluetooth + .defaultToSpeaker. Override via AudioSession.applyMode(...) if your app needs a different routing mode.
Lifecycle
Built-in UIApplication/NSApplication background-foreground observer. Local video pauses on background by default — opt out via LevelChatConfig.autoPauseOnBackground = false.
License
The SDK itself is MIT-licensed — embed in any app, commercial or personal, no royalties. The LevelChat server (signaling, SFU, recording) is BUSL-licensed and requires a paid commercial license for production use beyond the trial threshold. See Licensing.