tencent cloud

即时通信 IM

iOS(SwiftUI)

下载
聚焦模式
字号
最后更新时间: 2026-06-03 16:17:14
本文会引导您在 TUIKit SwiftUI 上创建群组。

开发环境要求

Xcode 15 及以上
iOS 15.0 及以上

前置条件

在构建界面之前,请确保您已经完成了以下 4 件事:
1. 在控制台创建了一个应用。
2. 在控制台创建了至少 2 个用户账号。
3. 集成了 TUIKit SwiftUI
4. 调用 LoginStorelogin 接口登录组件。
注意:
1. 每次启动应用,登录一次即可。
2. 请确保登录成功,我们建议您在登录成功的回调里进行下文的操作。
如果您尚未完成以上 4 步,请先参考 快速开始 中的对应步骤完成,否则在实现下文功能时可能遭遇阻碍。
如果您已经完成,请继续阅读下文。

创建群组

创建群组需要选择联系人,请先添加一些联系人,可参考文档:添加联系人
TUIKit SwiftUI 中没有直接可用的创建群组视图,需要组合几个不同的视图,例如 UserPicker、ConfigGroupInfoView 等,可参考下文的示例代码实现。创建群组成功后,您可以向该群组发送消息。
注意,如果您直接使用我们的示例代码,需要预填充以下几个参数:
sdkAppID,上文获取的 sdkAppID。
userID,操作者的 userID,也就是 快速开始 中创建的 user1。
userSig,操作者的 userSig,也就是 快速开始 中创建的 user1 的 userSig。
App 启动即加载创建群组选择联系人界面,示例代码如下所示:
// ContentView.swift
import SwiftUI

struct ContentView: View {
var body: some View {
CreateGroupPage()
}
}

// CreateGroupPage.swift
import AtomicX
import AtomicXCore
import SwiftUI

public struct CreateGroupPage: View {
@StateObject private var themeState = ThemeState.shared
@State private var selectedUsers: [UserPickerItem] = []
@State private var isLoggedIn = false
@State private var isLoggingIn = true
@State private var loginError: String? = nil
@State private var showConfigSheet = false
@State private var friendList: [ContactInfo] = []
@State private var createdGroupID: String? = nil

private let sdkAppID: Int32 = 1234567890 // TODO: Fill in your sdkAppID here
private let userID = "" // TODO: Fill in your userID here
private let userSig = "" // TODO: Fill in your generated userSig here

private let contactListStore = ContactListStore.create()

public var body: some View {
Group {
if isLoggedIn {
createGroupContentView
} else if isLoggingIn {
ProgressView("Logging in...")
} else {
VStack(spacing: 12) {
Image(systemName: "exclamationmark.triangle")
.font(.system(size: 40))
.foregroundColor(.orange)
Text(loginError ?? "Login failed")
.foregroundColor(.secondary)
}
}
}
.environmentObject(themeState)
.onAppear {
login()
}
}

// MARK: - Create Group Content

private var createGroupContentView: some View {
NavigationView {
VStack(spacing: 0) {
if let groupID = createdGroupID {
// Group created successfully
VStack(spacing: 16) {
Image(systemName: "checkmark.circle.fill")
.font(.system(size: 60))
.foregroundColor(.green)
Text("Group Created!")
.font(.system(size: 20, weight: .semibold))
Text("Group ID: \\(groupID)")
.font(.system(size: 15))
.foregroundColor(.secondary)
Button("Create Another Group") {
createdGroupID = nil
}
.padding(.top, 8)
}
.padding()
} else {
// UserPicker for selecting group members
UserPicker(
userList: userPickerItems,
maxCount: 0,
onSelectedChanged: { users in
selectedUsers = users
showConfigSheet = true
}
)
}
}
.navigationBarTitle("Create Group", displayMode: .inline)
}
.navigationViewStyle(StackNavigationViewStyle())
.onAppear {
contactListStore.fetchFriendList(completion: { _ in })
}
.onReceive(contactListStore.state.subscribe(StatePublisherSelector(keyPath: \\ContactListState.friendList))) { newFriendList in
self.friendList = newFriendList
}
.sheet(isPresented: $showConfigSheet, onDismiss: {
selectedUsers = []
}) {
ConfigGroupInfoView(
members: selectedUsers,
contactListStore: contactListStore,
onComplete: { groupID, groupName, conversationId in
showConfigSheet = false
if let gid = groupID {
print(">>>>> Group created: groupID=\\(gid), groupName=\\(groupName ?? ""), conversationId=\\(conversationId ?? "")")
createdGroupID = gid
}
},
onBack: {
showConfigSheet = false
}
)
}
}

// MARK: - Helper

private var userPickerItems: [UserPickerItem] {
friendList.map { contact in
UserPickerItem(
userID: contact.contactID,
avatarURL: contact.avatarURL,
title: contact.title ?? contact.contactID
)
}
}

// MARK: - Login

private func login() {
guard !userSig.isEmpty else {
isLoggingIn = false
loginError = "userSig is empty. Please fill in a valid userSig."
return
}
// Login is required when page appears.
LoginStore.shared.login(sdkAppID: sdkAppID, userID: userID, userSig: userSig) { result in
switch result {
case .success:
print(">>>>> Login success, userID: \\(userID)")
isLoggedIn = true
isLoggingIn = false
case .failure(let error):
print(">>>>> Login failed: \\(error.code), \\(error.message)")
loginError = "Login failed: \\(error.code), \\(error.message)"
isLoggingIn = false
}
}
}
}

运行效果如下所示:
搜索联系人
发送请求



更多实践

您可以本地 运行 Chat Demo 源码,探索更多的界面实现。

联系我们

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




帮助和支持

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

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

文档反馈