RoomStore is the dedicated module for room management within AtomicXCore, providing seamless integration with in-meeting call functionality. This section offers a comprehensive guide to developing and integrating in-meeting call features using RoomStore.RoomStore are summarized in the table below:Core Concept | Type | Core Responsibilities & Description |
enum | Indicates the state of an in-meeting call: none (default).calling (call in progress).timeout (call timed out).rejected (call rejected). | |
enum | Represents the outcome of an in-meeting call: success (call succeeded).alreadyInCalling (user is already being called).alreadyInRoom (user is already in the room). | |
enum | Specifies the reason for rejecting a call: rejected (actively rejected).inOtherRoom (user is in another room). | |
struct | Core data structure for in-meeting call operations. Stores caller details, callee details, and current call status. | |
enum | Represents real-time room events, including those related to in-meeting calls. | |
class | Central class for managing the room lifecycle. Provides functions for initiating and responding to in-meeting calls, retrieving the call list, and subscribing to roomEventPublisher for real-time call events. |
callUserToRoom method to invite multiple users to enter the room.import Foundationimport AtomicXCore// Initiate a callfunc callUserToRoom(userIDList: [String], timeout: Int = 30, extensionInfo: String? = nil) {RoomStore.shared.callUserToRoom(roomID: "roomID", userIDList: userIDList, timeout: timeout, extensionInfo: extensionInfo) { result inswitch result {case .success(let callResults):print("Call request sent successfully")case .failure(let error):print("Call request failed: [Error code: \\(error.code)]: \\(error.message)")}}}
cancelCall method to cancel ongoing call requests for multiple users.import Foundationimport AtomicXCore// Cancel a callfunc cancelCall(userIDList: [String]) {RoomStore.shared.cancelCall(roomID: "roomID", userIDList: userIDList) { result inswitch result {case .success():print("Call cancelled successfully")case .failure(let error):print("Call cancellation failed: [Error code: \\(error.code)]: \\(error.message)")}}}
getPendingCalls method to fetch the list of users currently being called in the room. This supports pagination.import Foundationimport AtomicXCore// Retrieve pending call listfunc getPendingCalls(roomID: String, cursor: String?) {// cursor is used for pagination. Pass nil on the first call to get the initial page; use the previous nextCursor value for subsequent calls.RoomStore.shared.getPendingCalls(roomID: roomID, cursor: cursor) { result inswitch result {case .success(let callInfo):print("Successfully retrieved call list, list info: \\(callInfo.0), pagination cursor: \\(callInfo.1)")case .failure(let error):print("Failed to retrieve call list: [Error code: \\(error.code)]: \\(error.message)")}}}
roomEventPublisher to receive real-time call lifecycle events. Listening to these events allows you to track the outcome of calls, update the UI, and trigger further business logic.import Combineimport AtomicXCoreimport Foundationprivate var cancellableSet = Set<AnyCancellable>()/// Subscribe to in-meeting call related eventsprivate func subscribeRoomCallEvents() {RoomStore.shared.roomEventPublisher.receive(on: DispatchQueue.main).sink { event inswitch event {case .onCallTimeout(let roomInfo, let call):print("Call timed out Room info: \\(roomInfo), Caller: \\(call.caller)")case .onCallAccepted(let roomInfo, let call):print("Call accepted Room info: \\(roomInfo), Callee: \\(call.callee)")case .onCallRejected(let roomInfo, let call, let reason):print("Call rejected Room info: \\(roomInfo), Callee: \\(call.callee), Rejection reason: \\(reason)")case .onCallHandledByOtherDevice(let roomInfo, let isAccepted):print("Call handled by another device Room info: \\(roomInfo) Result: \\(isAccepted)")default:// Handle other non-call related eventsbreak}}.store(in: &cancellableSet)}
Event Function | Trigger Timing & Description |
Triggered when the call request receives no response from the callee within the specified timeout period (set in callUserToRoom). The call ends automatically, and callers should display a "No answer" prompt. | |
Triggered when a callee clicks "Answer" or "Accept". Both parties have confirmed the call, and the caller should immediately enter the room or start streaming. | |
Triggered when the callee rejects the call or is already in another room, resulting in automatic rejection. Includes the rejection reason (active rejection or in another room). | |
Triggered when a user logged in on multiple devices (e.g., phone and tablet) answers or rejects a call on one device. The other device receives this notification to synchronize UI and dismiss the call interface. |
roomEventPublisher to listen for call actions from the caller in real time. These events help build the call notification UI and maintain the call chain state.import Combineimport AtomicXCoreimport Foundationprivate var cancellableSet = Set<AnyCancellable>()/// Subscribe to in-meeting call related eventsprivate func subscribeRoomCallEvents() {RoomStore.shared.roomEventPublisher.receive(on: DispatchQueue.main).sink { [weak self] event inguard let self = self else { return }switch event {case .onCallReceived(let roomInfo, let call, let extensionInfo):print("Received room call Room info: \\(roomInfo), Caller: \\(call.caller), Extension info: \\(extensionInfo)")case .onCallCancelled(let roomInfo, let call):print("Call cancelled Room info: \\(roomInfo), Caller: \\(call.caller)")case .onCallRevokedByAdmin(let roomInfo, let call, let operatorUser):print("Call revoked by admin Room info: \\(roomInfo), Caller: \\(call.caller), Operator: \\(operatorUser)")default:// Handle other non-call related eventsbreak}}.store(in: &cancellableSet)}
Event Function | Trigger Timing & Description |
Triggered when you receive a call invitation from another user. The callee should immediately show a "Call Notification" interface with caller information, room details, and "Answer" and "Reject" options. | |
Triggered when the caller cancels the call request before you respond. The callee should promptly close the incoming call UI and display a "Caller cancelled the call" message, returning to normal workflow. | |
Triggered when a room administrator or backend forcibly terminates the call due to permission changes, room dissolution, etc. The callee should stop the call process and hide related UI, handling it like a call cancellation. |
acceptCall or rejectCall methods to respond to call invitations.import Combineimport AtomicXCoreimport Foundationprivate var cancellableSet = Set<AnyCancellable>()/// Subscribe to in-meeting call related eventsprivate func subscribeRoomCallEvents() {RoomStore.shared.roomEventPublisher.receive(on: DispatchQueue.main).sink { event inswitch event {case .onCallReceived(let roomInfo, let call, let extensionInfo):print("Received room call Room info: \\(roomInfo), Caller: \\(call.caller), Extension info: \\(extensionInfo)")// Accept or reject call invitation operationsdefault:// Handle other non-call related eventsbreak}}.store(in: &cancellableSet)}// Accept call invitationfunc acceptCall(roomID: String) {RoomStore.shared.acceptCall(roomID: roomID) { result inswitch result {case .success:print("Call accepted successfully, Room ID: \\(roomID)")case .failure(let error):print("Call acceptance failed: [Error code: \\(error.code)] \\(error.message)")}}}// Reject call invitationfunc rejectCall(roomID: String, reason: CallRejectionReason = .rejected) {RoomStore.shared.rejectCall(roomID: roomID, reason: reason) { result inswitch result {case .success:print("Call rejected successfully, Room ID: \\(roomID)")case .failure(let error):print("Call rejection failed: [Error code: \\(error.code)] \\(error.message)")}}}
Store/Component | Description | API Documentation |
RoomStore | Room lifecycle management: create and join, join, leave, end room, update and retrieve room info, reserve room, call users outside the room, listen to passive room events (such as room dissolution, updates, etc.). |
피드백