TUIKit SwiftUI 是基于腾讯云 IM 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。参见 开通服务。集成并引入组件
下载源码
# 从 CNB 中克隆代码git clone https://cnb.cool/tencent/cloud/trtc/TUIKit_iOS_SwiftUI.git# 从 GitHub 中克隆代码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' douse_frameworks! :linkage => :staticpod '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:配置用户鉴权


警告:
步骤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 inDispatchQueue.main.async {switch result {case .success:// 进入会话列表界面等(步骤3)case .failure(let error):print("login failed: \\(error.code) \\(error.message)")}}}
步骤3:构建会话列表界面
import SwiftUIimport AtomicXCoreimport TUIChatKit_Swift// 进入会话列表页面NavigationLink(destination: ConversationsDestination())private struct ConversationsDestination: View {@State private var navigationInfo: NavigationInfo?@State private var showChat = falsevar body: some View {ConversationsPage(config: nil, // 会话操作配置,nil 使用默认配置onConversationClick: { info in // 会话打开回调,返回会话及可选的定位消息navigationInfo = infoshowChat = true}).navigationBarHidden(true).background(chatNavigationLink)}// 响应 onConversationClick 进入聊天页面,ChatPageDestination 的定义可以看步骤4构建聊天界面@ViewBuilderprivate 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 SwiftUIimport AtomicXCoreimport TUIChatKit_Swift// 进入单聊NavigationLink("进入单聊",destination: ChatPageDestination(conversation: makeTestC2CConversationInfo(),locateMessage: nil))private func makeTestC2CConversationInfo() -> ConversationInfo {var conversation = ConversationInfo(conversationID: ChatUtil.getC2CConversationID('test2'))conversation.type = .c2cconversation.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 = .groupconversation.title = "测试群:\\(MiniTestAccount.chatGroupID)"return conversation}private struct ChatPageDestination: View {@Environment(\\.dismiss) private var dismisslet conversation: ConversationInfovar locateMessage: MessageInfo? = nilvar 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, // 用户点击回调,返回用户 IDonMoreClick: 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 SwiftUIimport AtomicXCoreimport TUIChatKit_Swiftprivate 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 RTCRoomEngineimport TUICallKit_Swiftfunc initializeCall(sdkAppID: Int32, userID: String, userSig: String) {TUICallEngine.createInstance().`init`(sdkAppID, userId: userID, userSig: userSig) {TUICallKit.createInstance().enableIncomingBanner(enable: true)} fail: { code, message inprint("初始化通话失败:\\(code) \\(message ?? "")")}}
3. 发起视频通话:
import TUICallKit_Swiftfunc 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 SwiftUIimport AtomicXCoreimport 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 助手:知识咨询与代码集成
接入过程中可通过 IM MCP 查询 SDK API、排查错误或生成集成代码。参见 IM AI 助手接入说明。请说明使用 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 版本选择依赖,参见音视频产品的集成文档。


