Official Client SDK for LiveKit. Easily add video & audio capabilities to your iOS/macOS apps.
Docs and guides are at https://docs.livekit.io.
There is full source code of a iOS/macOS Swift UI Example App.
For minimal examples view this repo 👉 Swift SDK Examples
LiveKit for Swift is available as a Swift Package.
Add the dependency and also to your target
let package = Package(
...
dependencies: [
.package(name: "LiveKit", url: "https://github.com/livekit/client-sdk-swift.git", .upToNextMajor("0.9.5")),
],
targets: [
.target(
name: "MyApp",
dependencies: ["LiveKit"]
)
]
}
Go to Project Settings -> Swift Packages.
Add a new package and enter: https://github.com/livekit/client-sdk-swift
LiveKit provides an UIKit based VideoView
class that renders video tracks. Subscribed audio tracks are automatically played.
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: String = "ws://your_host"
let token: String = "your_jwt_token"
room.connect(url, token).then { room in
// Publish camera & mic
room.localParticipant?.setCamera(enabled: true)
room.localParticipant?.setMicrophone(enabled: true)
}.catch { error in
// failed to connect
}
}
}
extension RoomViewController: RoomDelegate {
func room(_ room: Room, localParticipant: LocalParticipant, didPublish publication: LocalTrackPublication) {
guard let track = publication?.track as? VideoTrack else {
return
}
DispatchQueue.main.async {
localVideoView.track = track
}
}
func room(_ room: Room, participant: RemoteParticipant, didSubscribe publication: RemoteTrackPublication, track: Track) {
guard let track = track as? VideoTrack else {
return
}
DispatchQueue.main.async {
remoteVideoView.track = track
}
}
}
Since VideoView
is a UI component, all operations (read/write properties etc) must be performed from the main
thread.
Other core classes can be accessed from any thread.
Delegates will be called on the SDK's internal thread.
Make sure any access to the UI is within the main thread, for example by using DispatchQueue.main.async
.
It is recommended to use weak var when storing references to objects created and managed by the SDK, such as Participant
, TrackPublication
etc. These objects are invalid when the Room
disconnects, and will be released by the SDK. Holding strong reference to these objects will prevent releasing Room
and other internal objects.
VideoView.track
property does not hold strong reference, so it's not required to set it to nil
.
- Currently,
VideoView
will use OpenGL for iOS Simulator. - Publishing the camera track is not supported by iOS Simulator.
It is recommended to turn off rendering of VideoView
s that scroll off the screen and isn't visible by setting false
to isEnabled
property and true
when it will re-appear to save CPU resources.
The following is an example for UICollectionView
(UIKit), implement UICollectionViewDelegate
and use willDisplay
/ didEndDisplaying
to update the isEnabled
property.
extension YourViewController: UICollectionViewDelegate {
func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
guard let yourCell = cell as? YourCell else { return }
yourCell.videoView.isEnabled = true
}
func collectionView(_ collectionView: UICollectionView, didEndDisplaying cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
guard let yourCell = cell as? YourCell else { return }
yourCell.videoView.isEnabled = false
}
}
Please join us on Slack to get help from our devs / community members. We welcome your contributions(PRs) and details can be discussed there.