
使用此 SDK 将实时视频、音频和数据功能添加到您的 Swift 应用中。通过连接到自托管或云托管的 LiveKit 服务器,您可以快速构建类似交互式直播或视频通话的应用程序,这仅需要几行代码。
注意
Swift SDK 的第 2 版与第 1 版有破坏性更改。请阅读 迁移指南,以了解详细的变化概述。
文档和指南位于 https://docs.livekit.io。
有一个 iOS/macOS Swift UI 示例应用程序 的完整源代码。
要查看最小示例,请访问此存储库 👉 Swift SDK 示例
LiveKit 的 Swift 版本作为 Swift 包提供。
将依赖项添加到您的目标
let package = Package(
...
dependencies: [
.package(name: "LiveKit", url: "https://github.com/livekit/client-sdk-swift.git", .upToNextMajor("2.0.5")),
],
targets: [
.target(
name: "MyApp",
dependencies: ["LiveKit"]
)
]
}
转到项目设置 -> Swift 包。
添加一个新的包并输入: https://github.com/livekit/client-sdk-swift
LiveKit 提供了一个基于 UIKit 的 VideoView
类来渲染视频轨道。订阅的音频轨道将自动播放。
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"
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 let error in {
// 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 {
localVideoView.track = track
}
}
func room(_: Room, participant _: RemoteParticipant, didSubscribeTrack publication: RemoteTrackPublication) {
guard let track = publication?.track as? VideoTrack else { return }
DispatchQueue.main.async {
remoteVideoView.track = track
}
}
}
请参阅 iOS 屏幕共享说明。
由于 VideoView
是一个 UI 组件,所有操作(读取/写入属性等)都必须在 main
线程上执行。
其他核心类可以从任何线程访问。
委托将在 SDK 的内部线程上调用。请确保对您应用程序的 UI 元素的所有访问都是从主线程进行的,例如,通过使用 @MainActor
或 DispatchQueue.main.async
。
建议使用 weak var 保存由 SDK 创建和管理的对象的引用,例如 Participant
、TrackPublication
等。当 Room
断开连接时,这些对象将变得无效,并由 SDK 释放。对这些对象的强引用将阻止释放 Room
和其他内部对象。
VideoView.track
属性不保留强引用,因此不需要将其设置为 nil
。
连接时,LiveKit 将自动管理底层的 AVAudioSession
。会话默认设置为 playback
类别。当发布本地流时,它将切换到 playAndRecord
。通常,它将选择合理的默认值并正确执行。
但是,如果您想自定义此行为,请覆盖 AudioManager.customConfigureAudioSessionFunc
以自定义底层的会话。请参阅 此处 的默认行为示例。
- 不支持通过 iOS 模拟器发布相机轨道。
建议关闭屏幕外的VideoView
渲染,通过将isEnabled
属性设置为false
来达到目的,当它将再次出现时将其设置为true
,以节省CPU资源。
据报道,UICollectionViewDelegate
的willDisplay
/ didEndDisplaying
对于此目的不可靠。具体来说,在某些iOS版本中,即使单元格可见,也可能调用didEndDisplaying
。
以下是不使用willDisplay
/ didEndDisplaying
的替代方法。
// 1. define a weak-reference set for all cells
private var allCells = NSHashTable<ParticipantCell>.weakObjects()
// in UICollectionViewDataSource...
public func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: ParticipantCell.reuseIdentifier, for: indexPath)
if let cell = cell as? ParticipantCell {
// 2. keep weak reference to the cell
allCells.add(cell)
// configure cell etc...
}
return cell
}
// 3. define a func to re-compute and update isEnabled property for cells that visibility changed
func reComputeVideoViewEnabled() {
let visibleCells = collectionView.visibleCells.compactMap { $0 as? ParticipantCell }
let offScreenCells = allCells.allObjects.filter { !visibleCells.contains($0) }
for cell in visibleCells.filter({ !$0.videoView.isEnabled }) {
print("enabling cell#\(cell.hashValue)")
cell.videoView.isEnabled = true
}
for cell in offScreenCells.filter({ $0.videoView.isEnabled }) {
print("disabling cell#\(cell.hashValue)")
cell.videoView.isEnabled = false
}
}
// 4. set a timer to invoke the func
self.timer = Timer.scheduledTimer(withTimeInterval: 0.1, repeats: true, block: { [weak self] _ in
self?.reComputeVideoViewEnabled()
})
// alternatively, you can call `reComputeVideoViewEnabled` whenever cell visibility changes (such as scrollViewDidScroll(_:)),
// but this will be harder to track all cases such as cell reload etc.
要查看完整示例,请参阅👉 UIKit Minimal Example
- 通过调用
LocalVideoTrack.createCameraTrack(options: CameraCaptureOptions(fps: 60))
创建一个LocalVideoTrack
。 - 使用
LocalParticipant.publish(videoTrack: track, publishOptions: VideoPublishOptions(encoding: VideoEncoding(maxFps: 60)))
进行发布。
如果您要将应用程序针对macOS Catalina,请确保执行以下操作以避免崩溃(ReplayKit找不到)
- 明确将"ReplayKit.framework"添加到"构建阶段" > "链接二进制与库"部分
- 将其设置为可选
- 我不确定为什么目前ReplayKit需要这样做。
- 如果您针对macOS 11.0+,则不需要这样做。
请加入我们的Slack以从我们的开发人员/社区成员那里获得帮助。我们欢迎您的贡献(PRs),并且在那里可以讨论细节。
LiveKit生态系统 | |
---|---|
实时SDKs | React组件 · JavaScript · iOS/macOS · Android · Flutter · React Native · Rust · Python · Unity (web) · Unity (beta) |
服务器APIs | Node.js · Golang · Ruby · Java/Kotlin · Python · Rust · PHP (社区) |
代理框架 | Python · Playground |
服务 | Livekit服务器 · Egress · Ingress · SIP |
资源 | 文档 · 示例应用程序 · 云 · 自托管 · CLI |