RoomParticipantStore 是 AtomicXCore 中专用于房间参与者管理的模块。该模块为多人房间场景提供了核心能力,支持构建完整的成员管理体系。

房间模式说明
在开始使用成员管理功能之前,需要了解
AtomicXCore 中房间模块支持的两种房间模式,不同模式下的成员管理功能有所区别:标准房间模式(Standard Room) | 网络研讨会房间模式(Webinar Room) |
适用场景:小型会议、团队协作、朋友聊天等。 成员特点:所有成员都是参与者,可以自由开启/关闭音视频设备。 管理特点:扁平化管理,房主可设置管理员进行协助管理。 | 适用场景:网络研讨会、在线培训等。 成员特点: 嘉宾(Participants):可以开启音视频设备,参与互动。 观众(Audience):只能观看,无法开启音视频设备。 管理特点:分层管理,支持观众与嘉宾身份转换。 |
核心功能
获取参与者列表:获取并展示当前房间内所有参与者信息(网络研讨会房间模式下,获取到的是嘉宾列表,嘉宾可以开启麦克风与其他嘉宾互动)。
获取观众列表:网络研讨会房间模式下,获取观众列表信息。
搜索房间内成员:搜索所在房间内的指定用户。
将观众提升为嘉宾:网络研讨会房间模式下,可以将观众提升为嘉宾,提升为嘉宾的用户可以开启麦克风与其他房间内的嘉宾互动。
将嘉宾降级为观众:网络研讨会房间模式下,可以将嘉宾降级为观众, 降级为观众的用户无法与房间内的嘉宾进行语音互动。
转移房主身份:房主可以将房主身份转移给房间内任意一名参与者。
设置/撤销管理员:房主可以设置参与者为管理员,同时也可撤销房间内的管理员。
将参与者移出房间:房主或者管理员可以将房间内任意一名参与者移出房间。
更新参与者信息:房间内所有人都可以更新自己的参与者信息。
音视频设备管理:支持申请/邀请打开摄像头、麦克风,关闭远端摄像头、麦克风,以及房主和管理员设置全体静音,全体禁用摄像头功能。
功能对比
功能 | 标准房间模式 | 网络研讨会房间模式 |
获取参与者列表 | 获取所有房间成员 | 获取嘉宾列表 |
获取观众列表 | 不适用 | 获取观众列表 |
搜索房间内成员 | 支持 | 支持 |
将观众提升为嘉宾 | 不适用 | 支持 |
将嘉宾降级为观众 | 不适用 | 支持 |
转移房主身份 | 支持 | 支持 |
设置/撤销管理员 | 支持 | 支持 |
移出房间 | 支持 | 支持 |
更新参与者信息 | 支持 | 支持 |
音视频设备管理 | 支持 | 支持 |
核心概念
在开始集成之前,需要通过下表了解一下
RoomParticipantStore相关的几个核心概念:核心概念 | 类型 | 核心职责与描述 |
struct | 代表参与者的核心数据模型,封装了参与者的完整信息和状态管理能力。 标准房间模式:代表房间内的所有成员。 网络研讨会房间模式:代表嘉宾,可以开启/关闭麦克风。 核心功能包括:参与者基本信息管理(用户 ID 、用户名称、用户头像、房间内角色身份)、参与者设备状态管理(麦克风状态,摄像头状态,屏幕分享状态,消息状态)。 | |
struct | 代表参与者状态管理的核心数据结构,负责维护房间内与参与者相关的状态信息。 核心属性: participantList 标准房间模式存储所有房间成员,网络研讨会房间模式存储嘉宾列表。participantListCursor 标准房间模式代表房间内所有成员列表的分页游标,网络研讨会房间模式代表房间内嘉宾列表的分页游标。localParticipant则代表自身所在房间内的参与者信息。 | |
enum | 代表房间内和参与者相关的实时事件。主要事件分为三大类:参与者进退房事件、 参与者身份改变事件,参与者设备控制事件。 | |
class | 这是参与者控制相关的核心类。功能包含:控制房间内参与者音视频状态、执行参与者管理操作,并通过订阅其 participantEventPublisher 来接收实时事件。 |
实现步骤
步骤1:组件集成
步骤2:获取参与者列表
在加入房间后,调用RoomParticipantStore的getParticipantList接口获取房间内参与者列表。
标准房间模式:获取房间内所有成员列表。
网络研讨会房间模式:获取房间内嘉宾列表。
import Foundationimport AtomicXCorefunc getParticipantList() {// 1. 业务逻辑说明// 前提:需要先完成进房操作,通过进房的roomID创建RoomParticipantStore实例let participantStore = RoomParticipantStore.create(roomID: "your_room_id")// 2. 首次获取参与者列表(从头开始)// 支持分页加载,可以通过 cursor 参数实现增量获取let initialCursor: String? = nil // nil 表示从第一页开始获取participantStore.getParticipantList(cursor: initialCursor) { result inswitch result {case .success(let participantInfo):print("成功获取参与者列表,数量: \\(participantInfo.0.count)")case .failure(let error):print("获取参与者列表失败 [错误码: \\(error.code)]: \\(error.message)")}}}
步骤3:获取观众列表
网络研讨会房间模式下,可以通过调用
RoomParticipantStore的getAudienceList接口获取房间内的观众列表。import Foundationimport AtomicXCorefunc getAudienceList() {// 前提:需要先完成进房操作, 并且进房时 roomType 设置为 webinar 类型。// 1. 业务逻辑说明// 通过进房的roomID创建RoomParticipantStore实例let participantStore = RoomParticipantStore.create(roomID: "your_room_id")// 2. 首次获取观众列表(从头开始)// 支持分页加载,可以通过 cursor 参数实现增量获取let initialCursor: String? = nil // nil 表示从第一页开始获取participantStore.getAudienceList(cursor: initialCursor) { result inswitch result {case .success(let audienceInfo):print("获取观众列表成功,观众数量: \\(audienceInfo.0.count)")case .failure(let error):print("获取观众列表失败 [错误码: \\(error.code)]: \\(error.message)")}}}
步骤4:搜索房间内成员
进入房间成功后,可以通过调用
RoomParticipantStore的searchUsers接口搜索房间内的成员。import Foundationimport AtomicXCorefunc searchUsers() {// 前提:需要先完成进房操作。// 1. 业务逻辑说明// 通过进房的roomID创建RoomParticipantStore实例let participantStore = RoomParticipantStore.create(roomID: "your_room_id")// 2. 通过用户名称为关键字搜索房间内成员let keyword = "userName"participantStore.searchUsers(keyword: keyword) { result inswitch result {case .success(let usersInfo):print("搜索房间成员成功,成员数量: \\(usersInfo.0.count)")case .failure(let error):print("搜索房间成员失败 [错误码: \\(error.code)]: \\(error.message)")}}}
步骤5:将观众提升为嘉宾
网络研讨会房间模式下,作为房主或管理员,调用
RoomParticipantStore的promoteAudienceToParticipant接口可以将房间内的观众提升为嘉宾。import Foundationimport AtomicXCorefunc promoteAudienceToParticipant(userID: String) {// 前提:需要先完成进房操作。// 1. 业务逻辑说明// 通过进房的 roomID 创建 RoomParticipantStore 实例let participantStore = RoomParticipantStore.create(roomID: "your_room_id")// 2. 调用 RoomParticipantStore 提升观众为参与者接口// 注意:只有房主或管理员才有权限执行此操作。participantStore.promoteAudienceToParticipant(userID: userID) { result inswitch result {case .success():print("提升为参与者成功")case .failure(let error):print("提升为参与者失败 [错误码: \\(error.code)]: \\(error.message)")}}}
作为房间内成员订阅
RoomParticipantStore的participantEventPublisher中的onAudiencePromotedToParticipant事件,被动接收观众提升为参与者的变化通知。import Foundationimport AtomicXCoreimport Combineprivate var cancellableSet = Set<AnyCancellable>()private func subscribeParticipantEvent() {// 1. 业务逻辑说明// 前提:需要先完成进房操作,通过进房的 roomID 创建 RoomParticipantStore 实例let participantStore = RoomParticipantStore.create(roomID: "your_room_id")// 2. 订阅参与者事件// participantEventPublisher 会推送所有参与者相关的事件participantStore.participantEventPublisher.receive(on: DispatchQueue.main) // 确保在主线程处理 UI 逻辑.sink { event inswitch event {case .onAudiencePromotedToParticipant(userInfo: let userInfo):print("观众被提升为参与者,userInfo: \\(userInfo)")default: break}}.store(in: &cancellableSet)}
步骤6:将嘉宾降级为观众
网络研讨会房间模式下,作为房主或管理员,调用
RoomParticipantStore的demoteParticipantToAudience接口可以将房间内的嘉宾降级为观众。import Foundationimport AtomicXCorefunc demoteParticipantToAudience(userID: String) {// 前提:需要先完成进房操作。// 1. 业务逻辑说明// 通过进房的 roomID 创建 RoomParticipantStore 实例let participantStore = RoomParticipantStore.create(roomID: "your_room_id")// 2. 调用 RoomParticipantStore 降级参与者为观众接口// 注意:只有房主或管理员才有权限执行此操作。participantStore.demoteParticipantToAudience(userID: userID) { result inswitch result {case .success():print("降级为观众成功")case .failure(let error):print("降级为观众失败 [错误码: \\(error.code)]: \\(error.message)")}}}
作为房间内成员订阅
RoomParticipantStore的participantEventPublisher中的onParticipantDemotedToAudience事件,被动接收参与者降级为观众的变化通知。import Foundationimport AtomicXCoreimport Combineprivate var cancellableSet = Set<AnyCancellable>()private func subscribeParticipantEvent() {// 1. 业务逻辑说明// 前提:需要先完成进房操作,通过进房的roomID创建RoomParticipantStore实例let participantStore = RoomParticipantStore.create(roomID: "your_room_id")// 1. 订阅参与者事件// participantEventPublisher 会推送所有参与者相关的事件participantStore.participantEventPublisher.receive(on: DispatchQueue.main) // 确保在主线程处理 UI 逻辑.sink { event inswitch event {case .onParticipantDemotedToAudience(userInfo: let userInfo):print("参与者被降级为观众,userInfo: \\(userInfo)")default: break}}.store(in: &cancellableSet)}
步骤7:转移房主身份
作为房主调用
RoomParticipantStore的transferOwner接口可以将房主身份直接转移给房间内任意一位参与者,转移后原房主身份将变为普通参与者,一个房间内有且仅有一名房主。import Foundationimport AtomicXCorefunc transferOwner(to userID: String) {// 1. 业务逻辑说明// 前提:需要先完成进房操作,通过进房的roomID创建RoomParticipantStore实例let participantStore = RoomParticipantStore.create(roomID: "your_room_id")// 2. 调用 RoomParticipantStore 转移房主接口// 注意:只有当前房主才有权限执行此操作,转移后原房主将变为普通用户participantStore.transferOwner(userID: userID) { result inswitch result {case .success():print("房主权限转移成功,新房主: \\(userID)")case .failure(let error):print("转移房主权限失败 [错误码: \\(error.code)]: \\(error.message)")}}}
作为参与者订阅
RoomParticipantStore的participantEventPublisher中的onOwnerChanged事件,被动接收房主变化通知。import Foundationimport AtomicXCoreimport Combineprivate var cancellableSet = Set<AnyCancellable>()private func subscribeParticipantEvent() {// 1. 业务逻辑说明// 前提:需要先完成进房操作,通过进房的roomID创建RoomParticipantStore实例let participantStore = RoomParticipantStore.create(roomID: "your_room_id")// 1. 订阅参与者事件// participantEventPublisher 会推送所有参与者相关的事件participantStore.participantEventPublisher.receive(on: DispatchQueue.main) // 确保在主线程处理 UI 逻辑.sink { event inswitch event {case .onOwnerChanged(let newOwner, let oldOwner):print("房主变更通知,newOwner: \\(newOwner), oldOwner: \\(oldOwner)")default: break}}.store(in: &cancellableSet)}
步骤8:设置/撤销管理员
作为房主调用
RoomParticipantStore的setAdmin接口,指定房间内任意一位参与者成为管理员,也可以将管理员身份撤销。import Foundationimport AtomicXCore// 业务逻辑说明// 前提:需要先完成进房操作,通过进房的roomID创建RoomParticipantStore实例let participantStore = RoomParticipantStore.create(roomID: "your_room_id")/// 设置用户为管理员func setUserAsAdmin(userID: String) {participantStore.setAdmin(userID: userID) { result inswitch result {case .success:print("成功设置用户 \\(userID) 为管理员")case .failure(let error):print("设置管理员失败 [错误码: \\(error.code)]: \\(error.message)")}}}/// 撤销用户的管理员权限func revokeUserAdmin(userID: String) {participantStore.revokeAdmin(userID: userID) { result inswitch result {case .success:print("成功撤销用户 \\(userID) 的管理员权限")case .failure(let error):print("撤销管理员失败 [错误码: \\(error.code)]: \\(error.message)")}}}
作为参与者订阅
RoomParticipantStore的participantEventPublisher中的onAdminSet和onAdminRevoked事件,被动接收参与者身份变化通知。import Foundationimport AtomicXCore// 业务逻辑说明// 前提:需要先完成进房操作,通过进房的roomID创建RoomParticipantStore实例let participantStore = RoomParticipantStore.create(roomID: "your_room_id")private var cancellableSet = Set<AnyCancellable>()/// 订阅参与者相关事件private func subscribeParticipantEvents() {participantStore.participantEventPublisher.receive(on: DispatchQueue.main) // 确保在主线程处理UI相关逻辑.sink { event inswitch event {case .onAdminSet(let userInfo):print("设置管理员事件通知,userInfo: \\(userInfo)")case .onAdminRevoked(let userInfo):print("撤销管理员事件通知,userInfo: \\(userInfo)")default: break}}.store(in: &cancellableSet)}
步骤9:将参与者移出房间
作为房主和管理员调用
RoomParticipantStore的kickUser可以将房间内参与者移出房间。import Foundationimport AtomicXCore// 业务逻辑说明// 前提:需要先完成进房操作,通过进房的roomID创建RoomParticipantStore实例let participantStore = RoomParticipantStore.create(roomID: "your_room_id")func kickUser(userID: String) {// 1. 业务逻辑说明// kickUser 接口用于将指定用户移出房间// 注意:只有房主或管理员才有权限执行此操作// 被移出的用户将立即离开房间,并收到相应的通知// 2. 调用 RoomParticipantStore 移出用户接口participantStore.kickUser(userID: userID) { result inswitch result {case .success():print("用户移出成功,被移出用户: \\(userID)")case .failure(let error):print("移出用户失败 [错误码: \\(error.code)]: \\(error.message)")}}}
作为参与者订阅
RoomParticipantStore的participantEventPublisher中的onKickedFromRoom事件,被动接收参与者被移出房间通知。import Foundationimport AtomicXCoreimport Combine// 业务逻辑说明// 前提:需要先完成进房操作,通过进房的roomID创建RoomParticipantStore实例let participantStore = RoomParticipantStore.create(roomID: "your_room_id")private var cancellableSet = Set<AnyCancellable>()/// 订阅参与者相关事件private func subscribeParticipantEvent() {participantStore.participantEventPublisher.receive(on: DispatchQueue.main) // 确保在主线程处理UI相关逻辑.sink { event inswitch event {case .onKickedFromRoom(let reason, let message):print("已被移出房间,被移出原因:\\(reason), 额外信息:\\(message)")default:break}}.store(in: &cancellableSet)}
步骤10:更新参与者信息
在加入房间后,调用
RoomParticipantStore的updateParticipantNameCard、updateParticipantMetaData更新您在房间里的参与者信息,包含:参与者名片信息,参与者自定义信息。import Foundationimport AtomicXCore// 业务逻辑说明// 前提:需要先完成进房操作,通过进房的roomID创建RoomParticipantStore实例let participantStore = RoomParticipantStore.create(roomID: "your_room_id")func updateParticipantNameCard(userID: String, nameCard: String) {// 1. 业务逻辑说明// updateParticipantNameCard 接口用于更新指定参与者的名片信息// 名片通常用于显示用户的自定义昵称或标识// 注意:通常只有管理员或用户本人才能修改名片// 2. 调用 RoomParticipantStore 更新名片接口participantStore.updateParticipantNameCard(userID: userID, nameCard: nameCard) { result inswitch result {case .success():print("名片更新成功,用户: \\(userID), 新名片: \\(nameCard)")case .failure(let error):print("名片更新失败 [错误码: \\(error.code)]: \\(error.message)")}}}func updateParticipantMetaData(userID: String, metaData: [String: String]) {// 1. 业务逻辑说明// updateParticipantMetaData 接口用于更新指定参与者的自定义信息// 存储自定义的业务数据,如用户标签、扩展属性等// 注意:自定义信息的键值对数量和大小有限制,键长度不能超过 50 字节,值长度不超过 200 字节// 2. 调用 RoomParticipantStore 更新自定义信息接口participantStore.updateParticipantMetaData(userID: userID, metaData: metaData) { result inswitch result {case .success():print("自定义信息数据更新成功,用户: \\(userID), 键数量: \\(metaData.count)")case .failure(let error):print("自定义信息更新失败 [错误码: \\(error.code)]: \\(error.message)")}}}
步骤11:邀请参与者打开其设备
作为房主和管理员调用
RoomParticipantStore的inviteToOpenDevice接口,邀请房间内参与者打开摄像头、麦克风。import Foundationimport AtomicXCore// 业务逻辑说明// 前提:需要先完成进房操作,通过进房的roomID创建RoomParticipantStore实例let participantStore = RoomParticipantStore.create(roomID: "your_room_id")func inviteUserToOpenDevice(userID: String, device: DeviceType, timeout: Int = 30) {// 1. 业务逻辑说明// inviteToOpenDevice 接口用于邀请指定用户开启某个设备// 通常用于管理员邀请参与者开启麦克风、摄像头或屏幕共享// 被邀请的用户会收到邀请通知,可以选择接受或拒绝// 2. 调用 RoomParticipantStore 邀请开启设备接口participantStore.inviteToOpenDevice(userID: userID, device: device, timeout: timeout) { result inswitch result {case .success():print("设备邀请发送成功,用户: \\(userID), 设备: \\(device)")case .failure(let error):print("设备邀请发送失败 [错误码: \\(error.code)]: \\(error.message)")}}}
作为参与者:
订阅
RoomParticipantStore的participantEventPublisher中的onDeviceInvitationReceived事件,被动接收邀请打开设备通知。接收到邀请打开设备通知后调用
RoomParticipantStore的acceptOpenDeviceInvitation或者declineOpenDeviceInvitation接口接受或拒绝邀请。import Foundationimport AtomicXCoreimport Combine// 业务逻辑说明// 前提:需要先完成进房操作,通过进房的roomID创建RoomParticipantStore实例let participantStore = RoomParticipantStore.create(roomID: "your_room_id")private var cancellableSet = Set<AnyCancellable>()/// 订阅参与者相关事件private func subscribeDeviceInvitationEvent() {participantStore.participantEventPublisher.receive(on: DispatchQueue.main) // 确保在主线程处理UI相关逻辑.sink { event inswitch event {case .onDeviceInvitationReceived(let invitation):print("收到设备邀请 - 设备: \\(invitation.device), 发送者: \\(invitation.senderUserName)")// 处理接受、拒绝设备邀请default: break}}.store(in: &cancellableSet)}func acceptOpenDeviceInvitation(userID: String, device: DeviceType) {// 处理接受邀请participantStore.acceptOpenDeviceInvitation(userID: userID, device: device) { result inswitch result {case .success():print("接受设备邀请成功 - 设备: \\(device)")case .failure(let error):print("接受设备邀请失败 [错误码: \\(error.code)]: \\(error.message)")}}}func declineOpenDeviceInvitation(userID: String, device: DeviceType) {// 处理拒绝邀请participantStore.declineOpenDeviceInvitation(userID: userID, device: device) { result inswitch result {case .success():print("拒绝设备邀请成功 - 设备: \\(device)")case .failure(let error):print("拒绝设备邀请失败 [错误码: \\(error.code)]: \\(error.message)")}}}
步骤12:关闭远端参与者设备
作为房主和管理员调用
RoomParticipantStore的closeParticipantDevice可以主动关闭远端参与者的摄像头、麦克风。import Foundationimport AtomicXCore// 业务逻辑说明// 前提:需要先完成进房操作,通过进房的roomID创建RoomParticipantStore实例let participantStore = RoomParticipantStore.create(roomID: "your_room_id")func closeParticipantDevice(userID: String, device: DeviceType) {// 1. 业务逻辑说明// closeParticipantDevice 接口用于房主或管理员关闭指定参与者的某个设备// 被关闭的用户会收到设备被关闭通知// 2. 调用 RoomParticipantStore 关闭参与者设备接口participantStore.closeParticipantDevice(userID: userID, device: device) { result inswitch result {case .success():print("关闭参与者设备成功 - 用户: \\(userID), 设备: \\(device)")case .failure(let error):print("关闭参与者设备失败: [错误码: \\(error.code)]: \\(error.message)")}}}
作为参与者订阅
RoomParticipantStore的participantEventPublisher中的onParticipantDeviceClosed事件,被动接收设备被关闭通知,并在UI上做出提示。import Foundationimport AtomicXCoreimport Combine// 业务逻辑说明// 前提:需要先完成进房操作,通过进房的roomID创建RoomParticipantStore实例let participantStore = RoomParticipantStore.create(roomID: "your_room_id")private var cancellableSet = Set<AnyCancellable>()/// 订阅参与者相关事件private func subscribeDeviceClosedEvent() {participantStore.participantEventPublisher.receive(on: DispatchQueue.main) // 确保在主线程处理UI相关逻辑.sink { event inswitch event {case .onParticipantDeviceClosed(let device, let operatorUser):print("设备被关闭 - 设备: \\(device), 操作者: \\(operatorUser.userName)")default:break}}.store(in: &cancellableSet)}
步骤13:参与者申请打开自己的设备
作为参与者调用
RoomParticipantStore的requestToOpenDevice接口,可以在房间被房主或管理员设置全体静音,全体禁用摄像头的场景下,主动申请打开摄像头、麦克风。import Foundationimport AtomicXCore// 业务逻辑说明// 前提:需要先完成进房操作,通过进房的roomID创建RoomParticipantStore实例let participantStore = RoomParticipantStore.create(roomID: "your_room_id")func requestToOpenDevice(device: DeviceType, timeout: Int = 30) {// 1. 业务逻辑说明// requestToOpenDevice 接口用于请求开启某个设备// 通常用于参与者申请开启麦克风、摄像头或屏幕共享// 房主和管理员会收到申请通知,可以选择同意或拒绝// 2. 调用 RoomParticipantStore 请求开启设备接口participantStore.requestToOpenDevice(device: device, timeout: timeout) { result inswitch result {case .success():print("设备开启请求发送成功 - 设备: \\(device)")case .failure(let error):print("设备开启请求发送失败 [错误码: \\(error.code)]: \\(error.message)")}}}
作为房主和管理员:
订阅
RoomParticipantStore的participantEventPublisher中的onDeviceRequestReceived事件,被动接收申请打开设备通知。接收到申请打开设备通知后,调用
RoomParticipantStore的approveOpenDeviceRequest或者rejectOpenDeviceRequest接口,批准或者拒绝申请。import Foundationimport AtomicXCoreimport Combine// 业务逻辑说明// 前提:需要先完成进房操作,通过进房的roomID创建RoomParticipantStore实例let participantStore = RoomParticipantStore.create(roomID: "your_room_id")private var cancellableSet = Set<AnyCancellable>()/// 订阅参与者相关事件private func subscribeDeviceRequestEvent() {participantStore.participantEventPublisher.receive(on: DispatchQueue.main) // 确保在主线程处理UI相关逻辑.sink { event inswitch event {case .onDeviceRequestReceived(let request):print("收到设备请求 - 用户: \\(request.senderUserName), 设备: \\(request.device)")// 批准、拒绝开启设备请求操作default:break}}.store(in: &cancellableSet)}func approveOpenDeviceRequest(device: DeviceType, userID: String) {// 批准开启请求participantStore.approveOpenDeviceRequest(device: device, userID: userID) { result inswitch result {case .success():print("批准设备请求成功 - 用户: \\(userID), 设备: \\(device)")case .failure(let error):print("批准设备请求失败: \\(error.message)")}}}func rejectOpenDeviceRequest(device: DeviceType, userID: String) {// 拒绝开启请求participantStore.rejectOpenDeviceRequest(device: device, userID: userID) { result inswitch result {case .success():print("拒绝设备请求成功 - 用户: \\(userID), 设备: \\(device)")case .failure(let error):print("拒绝设备请求失败: [错误码: \\(error.code)]: \\(error.message)")}}}
步骤14:全体禁用麦克风及摄像头
作为房主和管理员调用
RoomParticipantStore的disableAllDevices接口设置全员静音与全员禁用摄像头。开启后,房间内参与者的音视频开启权限将被限制,无法自主打开麦克风或摄像头设备。import Foundationimport AtomicXCore// 业务逻辑说明// 前提:需要先完成进房操作,通过进房的roomID创建RoomParticipantStore实例let participantStore = RoomParticipantStore.create(roomID: "your_room_id")func disableAllDevices(device: DeviceType, disable: Bool) {// 1. 业务逻辑说明// disableAllDevices 接口用于房主或管理员设置房间禁用、解禁房间内全体成员麦克风,摄像头// 设置后房间内参与者会收到禁用、解禁通知// 2. 调用 RoomParticipantStore 禁用、解禁全体设备接口participantStore.disableAllDevices(device: device, disable: disable) { result inswitch result {case .success():let action = disable ? "禁用" : "启用"print("\\(action)所有\\(device)成功")case .failure(let error):let action = disable ? "禁用" : "启用"print("\\(action)所有\\(device)失败 [错误码: \\(error.code)]: \\(error.message)")}}}
作为参与者订阅
RoomParticipantStore的participantEventPublisher中的onAllDevicesDisabled事件,可以监听全员静音或禁用摄像头指令,并在 UI 界面同步受控状态。受限状态下,摄像头与麦克风的主动开启功能将被锁定,参与者需发起开启申请,待房主或管理员核准授权后方可使用。import Foundationimport AtomicXCoreimport Combine// 业务逻辑说明// 前提:需要先完成进房操作,通过进房的roomID创建RoomParticipantStore实例let participantStore = RoomParticipantStore.create(roomID: "your_room_id")private var cancellableSet = Set<AnyCancellable>()/// 设置全局设备事件监听private func subscribeAllDevicesDisabledEvent() {participantStore.participantEventPublisher.receive(on: DispatchQueue.main) // 确保在主线程处理UI相关逻辑.sink { event inswitch event {case .onAllDevicesDisabled(let device, let disable, let operatorUser):let action = disable ? "禁用" : "启用"print("所有\\(device)被\\(action) - 操作者: \\(operatorUser.userName)")default:break}}.store(in: &cancellableSet)}
步骤15:监听参与者事件
订阅
RoomParticipantEvent参与者相关的被动事件。以订阅参与者加入房间、离开房间为例,示例代码如下:import Foundationimport AtomicXCoreimport Combine// 业务逻辑说明// 前提:需要先完成进房操作,通过进房的roomID创建RoomParticipantStore实例let participantStore = RoomParticipantStore.create(roomID: "your_room_id")private var cancellableSet = Set<AnyCancellable>()/// 设置参与者事件监听private func subscribeParticipantEvent() {participantStore.participantEventPublisher.receive(on: DispatchQueue.main) // 确保在主线程处理UI相关逻辑.sink { event inswitch event {case .onParticipantJoined(let participant):print("参与者加入房间 - 用户: \\(participant.userName), ID: \\(participant.userID)")case .onParticipantLeft(let participant):print("参与者离开房间 - 用户: \\(participant.userName), ID: \\(participant.userID)")default:break}}.store(in: &cancellableSet)}
订阅
RoomParticipantState 与参与者相关的属性状态变化。以订阅房间内正在说话的用户为例,示例代码如下:import Foundationimport AtomicXCoreimport Combine// 业务逻辑说明// 前提:需要先完成进房操作,通过进房的roomID创建RoomParticipantStore实例let participantStore = RoomParticipantStore.create(roomID: "your_room_id")private var cancellableSet = Set<AnyCancellable>()/// 设置参与者状态监听private func subscribeParticipantState() {participantStore.state.subscribe(StatePublisherSelector(keyPath: \\.speakingUsers)).map { $0 }.removeDuplicates { oldValue, newValue in// 比较两个字典是否相同,避免重复处理return oldValue == newValue}.receive(on: DispatchQueue.main).sink { speakingUsers inprint("说话用户状态变更 - 当前说话用户数: \\(speakingUsers.count)")}.store(in: &cancellableSet)}
API 文档
Store/Component | 功能描述 | API文档 |
RoomParticipantStore | 房间内参与者管理:设置管理员 / 转移房主 / 获取参与者列表 / 移出房间 / 参与者设备控制(例如关闭、邀请打开摄像头、麦克风等)/ 申请打开设备(例如申请打开摄像头、麦克风等)。 |