tencent cloud

即时通信 IM

iOS(SwiftUI)

下载
聚焦模式
字号
最后更新时间: 2026-11-05 14:35:03
TUIKit SwiftUI 是基于 Chat SDK 的声明式 UI 组件库,可快速实现聊天、会话列表、联系人、搜索及群组等功能。本文介绍如何集成组件并实现核心功能。TUIKit 界面效果如下图所示:
会话列表页
聊天页
音视频通话




集成 TUIKit SwiftUI

组件通过 AtomicXCore 管理数据,通过 TUIChatKit_Swift 提供 SwiftUI 页面。接入方可直接使用 ConversationsPage、ChatPage、ContactsPage,无须自行组装聊天界面。

前提条件

Xcode 16 或以上版本,Swift 5 语言模式。
iOS 15.0 或以上的真机或模拟器。App target 的 iOS Deployment Target 设置为 15.0 或更高,并与 Podfile 中的 platform :ios 保持一致。
CocoaPods,建议使用 1.16.x。
一个已开通的 Chat 应用,以及对应的 SDKAppID、UserID 和 UserSig。参见 开通服务。

集成并引入组件

下载源码

从 GitHub 克隆 TUIKit SwiftUI 源码:
git clone https://github.com/Tencent-RTC/TUIKit_iOS_SwiftUI.git
将仓库根目录下的 chat 文件夹整体复制到您的工程根目录下。复制完成后的目录结构如下:
YourApplication/
├── source/ # 您的工程代码
├── chat/ # Chat 源码
│ ├── demo/ # 示例工程
│ ├── demo_mini/ # 最小示例工程
│ └── uikit/ # TUIChatKit 组件库
│ ├── TUIChatKit_Swift.podspec
│ ├── components/ # UI 组件
│ ├── page/ # 完整页面
│ └── resources/ # 图片及本地化资源
├── Podfile # 依赖配置文件
├── YourApplication.xcworkspace # 您的项目文件
说明:
TUIKit_iOS_SwiftUI 是包含多个产品的开源仓库,Chat 的 UI 源码位于 chat/ 目录下(chat/uikit 为 SwiftUI 组件库,chat/demo 为示例工程)。模块目录可放在工程任意位置,只需在 Podfile 中设置正确的相对路径即可。实际集成到你的项目中时 demo 和 demo_mini 这两个目录应该删除。

集成组件

1. 在 Podfile 中添加依赖,按源码位置调整相对路径。以下假设已将 chat 文件夹整体复制到工程根目录,且 Podfile 位于同一工程根目录
platform :ios, '15.0'

# 将 YourApplication 替换为 App target 名称。依赖版本范围与当前聊天 Demo 保持一致。
target 'YourApplication' do
use_frameworks! :linkage => :static

pod 'TUIChatKit_Swift', :path => './chat/uikit/TUIChatKit_Swift.podspec'
pod 'AtomicXCore', '>= 4.3.10', '< 5.0'

# 需要音视频通话时添加
# pod 'TUICallKit_Swift'
end
2. Podfile 修改完毕后,执行以下命令,安装 TUIKit 组件。
pod install

# 如果无法安装 TUIKit 最新版本,执行以下命令更新本地的 CocoaPods 仓库列表。
# pod repo update
# pod update


接入步骤

完成上述集成后,参考以下步骤,您仅需几行代码即可在项目中快速搭建会话列表、聊天、联系人等核心界面。
说明:
代码接入可参考 demo_mini 工程。该工程以精简示例展示了 Chat 主要模块的接入方式,相比完整 Demo,代码更清晰、易于阅读。下文中的示例代码也大多来自该工程。

步骤1:配置用户鉴权

开发验证时,在 控制台 > 开发工具 > UserSig 工具 根据 UserID 获取测试 UserSig,用于登录鉴权。



警告:
正式环境应由服务端生成 UserSig,App 向业务服务获取签名。不要将 SDKSecretKey 写入客户端。详见 服务端生成 UserSig。

步骤2:用户登录

登录鉴权后才能正常使用组件的功能。调用 LoginStore 的 login 接口,传入上文获取的 sdkAppID、userID、userSig 进行登录鉴权。代码如下:
import AtomicXCore

// let yourSdkAppID: Int32 = 10_000_000_00 替换为您的实际 SDKAppID
// let testUserID = "testUserID" 替换为您的测试用户 ID
// let userSig = "xxxxxxx" 该用户对应的 UserSig,从步骤1的控制台获取

LoginStore.shared.login(sdkAppID: yourSdkAppID, userID: testUserID, userSig: userSig) { result in
DispatchQueue.main.async {
switch result {
case .success:
// 进入会话列表界面等(步骤3)
case .failure(let error):
print("login failed: \\(error.code) \\(error.message)")
}
}
}


步骤3:构建会话列表界面

登录成功后(步骤 2),使用 ConversationsPage 展示会话列表。用户点击会话时,onConversationClick 返回 NavigationInfo,接入方在回调中打开聊天页:
import SwiftUI
import AtomicXCore
import TUIChatKit_Swift

// 进入会话列表页面
NavigationLink(destination: ConversationsDestination())

private struct ConversationsDestination: View {
@State private var navigationInfo: NavigationInfo?
@State private var showChat = false

var body: some View {
ConversationsPage(
config: nil, // 会话操作配置,nil 使用默认配置
onConversationClick: { info in // 会话打开回调,返回会话及可选的定位消息
navigationInfo = info
showChat = true
}
)
.navigationBarHidden(true)
.background(chatNavigationLink)
}

// 响应 onConversationClick 进入聊天页面,ChatPageDestination 的定义可以看步骤4构建聊天界面
@ViewBuilder
private var chatNavigationLink: some View {
if let info = navigationInfo {
NavigationLink(
destination: ChatPageDestination(
conversation: info.conversation,
locateMessage: info.locateMessage
),
isActive: $showChat
) { EmptyView() }
.hidden()
}
}
}

步骤4:构建聊天界面

ChatPage 负责消息的展示与收发。构造 ChatPage 时必须传入一个 ConversationInfo 用于指定要进入的会话。其中 conversationID 与 type 是必填的关键字段,title 用于聊天页导航栏标题的初始展示。可以选填 messageListConfig 和 messageInputConfig,它们负责配置消息列表和消息输入模块的功能和样式等。
import SwiftUI
import AtomicXCore
import TUIChatKit_Swift

// 进入单聊
NavigationLink(
"进入单聊",
destination: ChatPageDestination(conversation: makeTestC2CConversationInfo(),
locateMessage: nil)
)

private func makeTestC2CConversationInfo() -> ConversationInfo {
var conversation = ConversationInfo(
conversationID: ChatUtil.getC2CConversationID('test2')
)
conversation.type = .c2c
conversation.title = "与 \\(MiniTestAccount.c2cChatUserID) 聊天"
return conversation
}

// 进入群聊
NavigationLink(
"进入群聊",
destination: ChatPageDestination(conversation: makeTestGroupConversationInfo(),
locateMessage: nil)
)

private func makeTestGroupConversationInfo() -> ConversationInfo {
var conversation = ConversationInfo(
conversationID: ChatUtil.getGroupConversationID('testGroup')
)
conversation.type = .group
conversation.title = "测试群:\\(MiniTestAccount.chatGroupID)"
return conversation
}

private struct ChatPageDestination: View {
@Environment(\\.dismiss) private var dismiss
let conversation: ConversationInfo
var locateMessage: MessageInfo? = nil

var body: some View {
ChatPage(
conversation: conversation, // 会话信息
locateMessage: locateMessage, // 需要定位的消息,nil 不指定定位消息
messageListConfig: nil, // 消息列表配置,nil 使用默认配置
messageInputConfig: nil, // 输入配置,nil 使用默认配置
isShowMoreButton: false, // 是否显示导航栏的更多按钮
showsNavigationBar: true, // 是否显示 SDK 自绘导航栏
topBannerView: nil, // 自定义顶部横幅,nil 不显示
onBack: { dismiss() }, // 返回按钮点击回调
onUserClick: nil, // 用户点击回调,返回用户 ID
onMoreClick: nil // 导航栏标题或更多按钮点击回调
)
.navigationBarHidden(true)
}
}
注意:
在聊天界面使用 相册/录像/视频通话等需要声明对应的权限,请在 App 的 Info.plist 中声明如下权限:
<key>NSCameraUsageDescription</key>
<string>需要访问您的相机权限,开启后才能发送图片或视频</string>
<key>NSMicrophoneUsageDescription</key>
<string>需要访问您的麦克风权限,开启后才能发送语音</string>
<key>NSPhotoLibraryAddUsageDescription</key>
<string>需要访问您的相册权限,开启后保存图片或视频</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>需要访问您的相册权限,开启后才能发送图片或视频</string>

步骤5:构建联系人界面

ContactsPage 展示当前用户的好友列表(按字母索引分组)与群列表入口 等。页面自带搜索栏,右上角的 +按钮内置了添加好友和加入群聊两个功能入口。
import SwiftUI
import AtomicXCore
import TUIChatKit_Swift

private struct ContactsDestination: View {
var body: some View {
ContactsPage(
config: nil, // 联系人列表配置,nil 使用默认配置
onContactClick: { item in // 联系人点击回调,进入联系人信息
// openChat(makeC2CConversation(item))
},
onGroupClick: { item in // 群点击回调,进入群信息
// openChat(makeGroupConversation(item))
}
)
.navigationBarTitleDisplayMode(.inline)
.navigationBarHidden(true)
// .background(chatNavigationLink) // 挂载隐藏导航链接,用于打开聊天页
}
}

步骤6:音视频通话

音视频通话能力由 TUICallKit_Swift 组件提供(Podfile 中需添加 pod 'TUICallKit_Swift')。
1. 开通音视频通话服务,请参考 开通音视频服务。
2. 登录成功后初始化通话引擎。
LoginStore 登录只建立了消息通道,在登录成功后,通话引擎需单独初始化:
import RTCRoomEngine
import TUICallKit_Swift

func initializeCall(sdkAppID: Int32, userID: String, userSig: String) {
TUICallEngine.createInstance().`init`(sdkAppID, userId: userID, userSig: userSig) {
TUICallKit.createInstance().enableIncomingBanner(enable: true)
} fail: { code, message in
print("初始化通话失败:\\(code) \\(message ?? "")")
}
}
3. 发起视频通话:
import TUICallKit_Swift

func startVideoCall(userID: String) {
TUICallKit.createInstance().calls(
userIdList: [userID], // 被叫用户 ID 列表。单人通话传一个元素;传多个则为群组通话
mediaType: .video, // 通话类型:.video 视频通话、.audio 语音通话
params: nil,
completion: nil
)
}
调用后 TUICallKit 会自动弹出全屏通话界面(含呼叫等待、接通、挂断全流程 UI),无需自行实现。
4. 如何移除音视频通话功能?
ChatPage 默认显示通话入口,如果你不需要音视频通话功能。可以在 步骤 4 创建聊天界面 的 messageInputConfig 参数中关闭音视频通话开关,messageInputConfig 关闭音视频通话的配置如下:
import SwiftUI
import AtomicXCore
import TUIChatKit_Swift

// 构造不带音视频通话的 messageInputConfig 传入该config, 输入 View 的更多面板中没有音视频通话
private func makeMessageInputConfig () -> ChatMessageInputConfig {
var inputConfig = ChatMessageInputConfig()
inputConfig.isShowVideoCall = false // 关闭视频通话
inputConfig.isShowAudioCall = false // 关闭音频通话
return inputConfig
}
说明:
更多完整示例可参考 chat/demo_mini。页面的配置对象参数可以省略或传 nil,组件会使用默认配置,只需设置需要覆盖的选项。

AI 助手:知识咨询与代码集成

接入过程中可通过 MCP 使用 AI 助手查询 SDK API、排查错误或生成集成代码。参见 MCP 配置。请说明使用 iOS SwiftUI 和 TUIChatKit_Swift,避免混用 UIKit 接口。

常见问题

编译提示 No such module 'ChatUIKit' 怎么办?

当前模块名为 TUIChatKit_Swift,源码应使用 import TUIChatKit_Swift。确认 Podfile 路径正确,执行 pod install 后打开 .xcworkspace。资源包 ChatUIKitBundle 无须改名。

页面提示找不到 ThemeState,或出现两套导航栏怎么办?

参照步骤2,在根视图注入 .environmentObject(ThemeState.shared),并隐藏系统导航栏。ChatPage.onBack 是返回事件回调,需要接入方执行导航返回。

登录失败,提示签名错误怎么办?

检查 SDKAppID、UserID、UserSig 是否匹配,以及签名是否过期。开发时重新生成测试签名;正式环境检查服务端生成签名的参数。

TUICallKit 和已有音视频库冲突怎么办?

避免同时引入不同类型或版本的腾讯云音视频底层库,按项目实际使用的通话 SDK 版本选择依赖,参见音视频产品的集成文档。

联系我们

如果您在接入或使用过程中有任何疑问或建议,欢迎 联系我们 提交反馈。

帮助和支持

本页内容是否解决了您的问题?

填写满意度调查问卷,共创更好文档体验。

文档反馈