The LiveKit icon, the name of the repository and some sample code in the background.

适用于 LiveKit 的 iOS/macOS Swift SDK

使用此 SDK 将实时视频、音频和数据功能添加到您的 Swift 应用程序中。通过连接到 LiveKit 云服务或自托管服务器,您只需几行代码即可快速构建多模态 AI、直播或视频通话等应用程序。

文档和示例应用

注意

Swift SDK 的版本 2 包含与版本 1 的不兼容变更。请阅读迁移指南,详细了解变更内容。

文档和指南位于 https://docs.livekit.io

这里有iOS/macOS Swift UI 示例应用的完整源代码。

如需查看最简示例,请访问此仓库 👉 Swift SDK 示例

安装

LiveKit for Swift 以 Swift Package 的形式提供。

Package.swift

添加依赖项,并添加到您的 target 中

let package = Package(
  ...
  dependencies: [
    .package(name: "LiveKit", url: "https://github.com/livekit/client-sdk-swift.git", .upToNextMajor("2.1.1")),
  ],
  targets: [
    .target(
      name: "MyApp",
      dependencies: ["LiveKit"]
    )
  ]
}

XCode

转到 “Project Settings -> Swift Packages”。

添加一个新的 package 并输入:https://github.com/livekit/client-sdk-swift

iOS 用法

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"

        Task {
            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 {
                // 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 {
            self.localVideoView.track = track
        }
    }

    func room(_: Room, participant _: RemoteParticipant, didSubscribeTrack publication: RemoteTrackPublication) {
        guard let track = publication.track as? VideoTrack else { return }
        DispatchQueue.main.async {
            self.remoteVideoView.track = track
        }
    }
}

屏幕共享

请参阅 iOS 屏幕共享说明

集成注意事项

线程安全

由于 VideoView 是一个 UI 组件,因此所有操作(读/写属性等)都必须从 main 线程执行。

可以从任何线程访问其他核心类。

委托将在 SDK 的内部线程上调用。请确保从主线程访问应用程序的 UI 元素,例如使用 @MainActorDispatchQueue.main.async

内存管理

建议在使用 weak var 时存储对 SDK 创建和管理的对象(如 ParticipantTrackPublication 等)的引用。当 Room 断开连接时,这些对象将失效,并会被 SDK 释放。保持对这些对象的强引用将阻止释放 Room 和其他内部对象。

VideoView.track 属性不持有强引用,因此不需要将其设置为 nil

AudioSession 管理

LiveKit 将在连接时自动管理底层的 AVAudioSession。会话将默认设置为 playback 类别。当发布本地流时,它将切换到 playAndRecord。一般来说,它会选择合理的默认值并执行正确的操作。

但是,如果您想自定义此行为,您可以覆盖 AudioManager.customConfigureAudioSessionFunc 以自行管理底层会话。请参阅 此处的示例 以了解默认行为。

与 CallKit 集成

要与 CallKit 集成以实现后台触发的来电,LiveKit 的音频会话必须与 CallKit 的音频会话同步

  1. import LiveKitWebRTC 添加到您的 CallProvider 文件。
  2. 在您的 CXProviderDelegate 实现中,添加以下内容
func provider(_ provider: CXProvider, didActivate audioSession: AVAudioSession){
    LKRTCAudioSession.sharedInstance().audioSessionDidActivate(audioSession)
    // ...
}
func provider(_ provider: CXProvider, didDeactivate audioSession: AVAudioSession) {
    LKRTCAudioSession.sharedInstance().audioSessionDidDeactivate(audioSession)
    // ...
}

iOS 模拟器限制

ScrollView 性能

建议关闭滚动到屏幕外且不可见的 VideoView 的渲染,方法是将 isEnabled 属性设置为 false,并在重新出现时设置为 true,以节省 CPU 资源。

据报告,UICollectionViewDelegatewillDisplay / 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

常见问题

如何在 60 FPS 下发布摄像头?

已知问题

避免在 macOS Catalina 上崩溃

如果您的应用程序的目标是 macOS Catalina,请确保执行以下操作以避免崩溃(找不到 ReplayKit)

  1. 显式将 "ReplayKit.framework" 添加到 “Build Phases > Link Binary with Libraries” 部分
  2. 将其设置为 Optional

replykit

获取帮助/贡献

请加入我们的 Slack 以获得我们开发人员/社区成员的帮助。我们欢迎您的贡献(PR),详细信息可以在那里讨论。


LiveKit 生态系统
LiveKit SDK 浏览器 · iOS/macOS/visionOS · Android · Flutter · React Native · Rust · Node.js · Python · Unity · Unity (WebGL)
服务器 API Node.js · Golang · Ruby · Java/Kotlin · Python · Rust · PHP (社区) · .NET (社区)
UI 组件 React · Android Compose · SwiftUI
代理框架 Python · Node.js · Playground
服务 LiveKit 服务器 · Egress · Ingress · SIP
资源 文档 · 示例应用 · 云服务 · 自托管 · CLI