RoomParticipantStore is a specialized module within AtomicXCore designed for managing room participants. It provides essential functionality for conference scenarios, enabling you to build a robust participant management system.
RoomParticipantStore are summarized in the table below:Core Concept | Type | Main Responsibilities & Description |
struct | Represents the core data model for guests, encapsulating complete information and state management capabilities, including microphone control. Main functions include: basic guest information management (user ID, user name, avatar, room role), device state management (microphone status, camera status, screen sharing status, message status). | |
struct | Provides the data structure for managing participant states within the room, maintaining relevant status information. Main properties: participantList: Guest list.audienceList: Audience list.adminList: Admin list.localParticipant: Information about the current user in the room. | |
enum | Represents real-time events related to room participants. | |
class | Core class for participant control. Functions include: guest audio/video control, participant management, role switching between guest and audience, and subscribing to participantEventPublisher for real-time events. |
getParticipantList method in RoomParticipantStore to obtain the guest list.import Foundationimport AtomicXCorefunc getParticipantList() {// Prerequisite: User must have entered the room and created a RoomParticipantStore instance using the roomIDlet participantStore = RoomParticipantStore.create(roomID: "webinar_123456")// Retrieve the initial guest list (pagination supported; cursor parameter for incremental fetch)var initialCursor: String? = nil // nil fetches from the first pageparticipantStore.getParticipantList(cursor: initialCursor) { result inswitch result {case .success(let participantInfo):print("Successfully retrieved participant list, count: \\(participantInfo.0.count)")case .failure(let error):print("Failed to retrieve participant list [Error code: \\(error.code)]: \\(error.message)")}}}
getAudienceList method in RoomParticipantStore to fetch the audience list.import Foundationimport AtomicXCorefunc getAudienceList() {// Prerequisite: User must have entered the room and set roomType to WEBINARlet participantStore = RoomParticipantStore.create(roomID: "webinar_123456")// Retrieve the initial audience list (pagination supported; cursor parameter for incremental fetch)let initialCursor: String? = nil // nil fetches from the first pageparticipantStore.getAudienceList(cursor: initialCursor) { result inswitch result {case .success(let audienceInfo):print("Successfully retrieved audience list, count: \\(audienceInfo.0.count)")case .failure(let error):print("Failed to retrieve audience list [Error code: \\(error.code)]: \\(error.message)")}}}
searchUsers method in RoomParticipantStore to search for members.import Foundationimport AtomicXCorefunc searchUsers() {// Prerequisite: User must have entered the roomlet participantStore = RoomParticipantStore.create(roomID: "webinar_123456")// Search for members by keyword (user name)let keyword = "userName"participantStore.searchUsers(keyword: keyword) { result inswitch result {case .success(let usersInfo):print("Successfully searched room members, count: \\(usersInfo.0.count)")case .failure(let error):print("Failed to search room members [Error code: \\(error.code)]: \\(error.message)")}}}
promoteAudienceToParticipant method in RoomParticipantStore to promote an audience member to guest.import Foundationimport AtomicXCorefunc promoteAudienceToParticipant(userID: String) {// Prerequisite: User must have entered the roomlet participantStore = RoomParticipantStore.create(roomID: "webinar_123456")// Only host or admin can perform this actionparticipantStore.promoteAudienceToParticipant(userID: userID) { result inswitch result {case .success():print("Promotion to guest successful")case .failure(let error):print("Promotion to guest failed [Error code: \\(error.code)]: \\(error.message)")}}}
onAudiencePromotedToParticipant event in participantEventPublisher:import Foundationimport AtomicXCoreimport Combineprivate var cancellableSet = Set<AnyCancellable>()private func subscribeParticipantEvent() {// Prerequisite: User must have entered the room and created RoomParticipantStore instancelet participantStore = RoomParticipantStore.create(roomID: "webinar_123456")participantStore.participantEventPublisher.receive(on: DispatchQueue.main).sink { event inswitch event {case .onAudiencePromotedToParticipant(userInfo: let userInfo):print("Audience promoted to guest, userInfo: \\(userInfo)")default: break}}.store(in: &cancellableSet)}
demoteParticipantToAudience method in RoomParticipantStore to demote a guest to audience.import Foundationimport AtomicXCorefunc demoteParticipantToAudience(userID: String) {// Prerequisite: User must have entered the roomlet participantStore = RoomParticipantStore.create(roomID: "webinar_123456")// Only host or admin can perform this actionparticipantStore.demoteParticipantToAudience(userID: userID) { result inswitch result {case .success():print("Demotion to audience successful")case .failure(let error):print("Demotion to audience failed [Error code: \\(error.code)]: \\(error.message)")}}}
onParticipantDemotedToAudience event in participantEventPublisher:import Foundationimport AtomicXCoreimport Combineprivate var cancellableSet = Set<AnyCancellable>()private func subscribeParticipantEvent() {// Prerequisite: User must have entered the room and created RoomParticipantStore instancelet participantStore = RoomParticipantStore.create(roomID: "webinar_123456")participantStore.participantEventPublisher.receive(on: DispatchQueue.main).sink { event inswitch event {case .onParticipantDemotedToAudience(userInfo: let userInfo):print("Guest demoted to audience, userInfo: \\(userInfo)")default: break}}.store(in: &cancellableSet)}
setAdmin method to grant admin privileges, or revokeAdmin to remove them:import Foundationimport AtomicXCorelet participantStore = RoomParticipantStore.create(roomID: "webinar_123456")/// Set user as adminfunc setUserAsAdmin(userID: String) {participantStore.setAdmin(userID: userID) { result inswitch result {case .success:print("Successfully set user \\(userID) as admin")case .failure(let error):print("Failed to set admin [Error code: \\(error.code)]: \\(error.message)")}}}/// Revoke admin privilegesfunc revokeUserAdmin(userID: String) {participantStore.revokeAdmin(userID: userID) { result inswitch result {case .success:print("Successfully revoked admin privileges for user \\(userID)")case .failure(let error):print("Failed to revoke admin [Error code: \\(error.code)]: \\(error.message)")}}}
onAdminSet and onAdminRevoked events in participantEventPublisher for notifications about admin role changes:import Foundationimport AtomicXCoreimport Combinelet participantStore = RoomParticipantStore.create(roomID: "webinar_123456")private var cancellableSet = Set<AnyCancellable>()private func subscribeParticipantEvents() {participantStore.participantEventPublisher.receive(on: DispatchQueue.main).sink { event inswitch event {case .onAdminSet(let userInfo):print("Admin privileges granted, userInfo: \\(userInfo)")case .onAdminRevoked(let userInfo):print("Admin privileges revoked, userInfo: \\(userInfo)")default: break}}.store(in: &cancellableSet)}
kickUser in RoomParticipantStore to remove a participant from the room:import Foundationimport AtomicXCorelet participantStore = RoomParticipantStore.create(roomID: "webinar_123456")func kickUser(userID: String) {// Only host or admin can perform this action; removed users exit the room immediately and receive a notificationparticipantStore.kickUser(userID: userID) { result inswitch result {case .success():print("User removed successfully: \\(userID)")case .failure(let error):print("Failed to remove user [Error code: \\(error.code)]: \\(error.message)")}}}
onKickedFromRoom event in participantEventPublisher to receive removal notifications:import Foundationimport AtomicXCoreimport Combinelet participantStore = RoomParticipantStore.create(roomID: "webinar_123456")private var cancellableSet = Set<AnyCancellable>()private func subscribeParticipantEvent() {participantStore.participantEventPublisher.receive(on: DispatchQueue.main).sink { event inswitch event {case .onKickedFromRoom(let reason, let message):print("Removed from room. Reason: \\(reason), Details: \\(message)")default:break}}.store(in: &cancellableSet)}
closeParticipantDevice in RoomParticipantStore to proactively close a guest's camera or microphone:import Foundationimport AtomicXCorelet participantStore = RoomParticipantStore.create(roomID: "webinar_123456")func closeParticipantDevice(userID: String, device: DeviceType) {// Host or admin can close devices; affected users receive a notificationparticipantStore.closeParticipantDevice(userID: userID, device: device) { result inswitch result {case .success():print("Closed device for user: \\(userID), device: \\(device)")case .failure(let error):print("Failed to close device [Error code: \\(error.code)]: \\(error.message)")}}}
closeParticipantDevice is only applicable to guests. Audience members do not have audio/video device permissions and are unaffected by this operation.onParticipantDeviceClosed event in participantEventPublisher to receive device closure notifications:import Foundationimport AtomicXCoreimport Combinelet participantStore = RoomParticipantStore.create(roomID: "webinar_123456")private var cancellableSet = Set<AnyCancellable>()private func subscribeDeviceClosedEvent() {participantStore.participantEventPublisher.receive(on: DispatchQueue.main).sink { event inswitch event {case .onParticipantDeviceClosed(let device, let operatorUser):print("Device closed: \\(device), by: \\(operatorUser.userName)")default:break}}.store(in: &cancellableSet)}
disableUserMessage in RoomParticipantStore to mute or unmute specific users. Muted users are tracked in messageDisabledUserList.import Foundationimport AtomicXCoreimport Combinelet participantStore = RoomParticipantStore.create(roomID: "webinar_123456")private var cancellableSet = Set<AnyCancellable>()func disableUserMessage(userID: String, disable: Bool) {// Host or admin can mute/unmute members; affected users are notifiedparticipantStore.disableUserMessage(userID: userID, disable: disable) { result inswitch result {case .success():print("\\(disable ? "Mute" : "Unmute") successful - user: \\(userID)")case .failure(let err):print("\\(disable ? "Mute" : "Unmute") user chat failed - error code: \\(err.code), error message: \\(err.message)")}}}
messageDisabledUserList is only applicable in conference (Webinar) rooms and maintains the list of individually muted users.onUserMessageDisabled event in participantEventPublisher for mute/unmute chat notifications:import Foundationimport AtomicXCoreimport Combinelet participantStore = RoomParticipantStore.create(roomID: "webinar_123456")private var cancellableSet = Set<AnyCancellable>()private func subscribeDeviceClosedEvent() {participantStore.participantEventPublisher.receive(on: DispatchQueue.main).sink { event inswitch event {case .onUserMessageDisabled(let disable, let user):print("User \\(disable ? "muted" : "unmuted"), operator: \\(user.userName)")default:break}}.store(in: &cancellableSet)}
disableAllDevices in RoomParticipantStore to mute all microphones, disable all cameras, or disable all screen sharing. When enabled, guests are prevented from activating their audio/video devices or screen sharing.import Foundationimport AtomicXCorelet participantStore = RoomParticipantStore.create(roomID: "webinar_123456")func disableAllDevices(device: DeviceType, disable: Bool) {// Host or admin can mute/unmute all devices; participants receive notificationsparticipantStore.disableAllDevices(device: device, disable: disable) { result inswitch result {case .success():let action = disable ? "Mute" : "Unmute"print("\\(action) all \\(device) successful")case .failure(let error):let action = disable ? "Mute" : "Unmute"print("\\(action) all \\(device) failed [Error code: \\(error.code)]: \\(error.message)")}}}
onAllDevicesDisabled event in participantEventPublisher to stay updated on mute all or disable all video actions, and update UI status accordingly. When global restrictions are applied, participants cannot enable camera or microphone unless approved by the host or admin.import Foundationimport AtomicXCoreimport Combinelet participantStore = RoomParticipantStore.create(roomID: "webinar_123456")private var cancellableSet = Set<AnyCancellable>()private func subscribeAllDevicesDisabledEvent() {participantStore.participantEventPublisher.receive(on: DispatchQueue.main).sink { event inswitch event {case .onAllDevicesDisabled(let device, let disable, let operatorUser):let action = disable ? "Mute" : "Unmute"print("All \\(device) \\(action) - operator: \\(operatorUser.userName)")default:break}}.store(in: &cancellableSet)}
disableAllMessages in RoomParticipantStore to mute chat for all members. When enabled, all chat messages are restricted.import Foundationimport AtomicXCorelet participantStore = RoomParticipantStore.create(roomID: "webinar_123456")func disableAllMessages(disable: Bool) {// Host or admin can mute/unmute chat for all members; everyone receives notificationsparticipantStore.disableAllMessages(disable: disable) { result inswitch result {case .success():let action = disable ? "Mute" : "Unmute"print("All members chat \\(action) successful")case .failure(let error):let action = disable ? "Mute" : "Unmute"print("All members chat \\(action) failed [Error code: \\(error.code)]: \\(error.message)")}}}
onAllMessagesDisabled event in participantEventPublisher for global chat mute/unmute notifications:import Foundationimport AtomicXCoreimport Combinelet participantStore = RoomParticipantStore.create(roomID: "webinar_123456")private var cancellableSet = Set<AnyCancellable>()private func subscribeAllDevicesDisabledEvent() {participantStore.participantEventPublisher.receive(on: DispatchQueue.main).sink { event inswitch event {case .onAllMessagesDisabled(let disable, let operatorUser):let action = disable ? "Mute" : "Unmute"print("Chat \\(action) - operator: \\(operatorUser.userName)")default:break}}.store(in: &cancellableSet)}
RoomParticipantEvent for device requests and other participant-related events:import Foundationimport AtomicXCoreimport Combinelet participantStore = RoomParticipantStore.create(roomID: "webinar_123456")private var cancellableSet = Set<AnyCancellable>()private func subscribeAllDevicesDisabledEvent() {participantStore.participantEventPublisher.receive(on: DispatchQueue.main).sink { event inswitch event {case .onDeviceRequestReceived(let request):print("Device request received - device type: \\(request.device), user: \\(request.senderUserID)")default:break}}.store(in: &cancellableSet)}
RoomParticipantState, such as the number of users currently speaking:import Foundationimport AtomicXCoreimport Combinelet participantStore = RoomParticipantStore.create(roomID: "webinar_123456")private var cancellableSet = Set<AnyCancellable>()private func subscribeParticipantState() {participantStore.state.subscribe(StatePublisherSelector(keyPath: \\.speakingUsers)).map { $0 }.removeDuplicates { oldValue, newValue in// Avoid duplicate processing by comparing dictionariesreturn oldValue == newValue}.receive(on: DispatchQueue.main).sink { speakingUsers inprint("Speaking user state changed - current speakers: \\(speakingUsers.count)")}.store(in: &cancellableSet)}
Store/Component | Description | API Documentation |
RoomParticipantStore | Participant management: set admin, transfer host, retrieve guest list, remove from room, guest device control (such as closing or inviting to open microphone, etc.). |
피드백