| 会话列表页 | 聊天页 | 音视频通话 |
| | | |
一、问卷反馈
注意:说明:
注意:花 30 秒,帮 iOS TUIKit 变得更好用!
注意:正在接入、已经跑通、还是卡住了?都欢迎你填写 iOS 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 或者 GitHub 克隆 TUIKit SwiftUI 源码:
# 从 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' 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:配置用户鉴权
开发验证时,在 即时通信 IM 控制台 根据 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 SwiftUIimport AtomicXCoreimport 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 SwiftUIimport AtomicXCoreimport 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 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 in print("初始化通话失败:\\(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 版本选择依赖,参见音视频产品的集成文档。
20、联系我们
如果你在接入或使用过程中有任何疑问或建议,欢迎 联系我们 提交反馈。