Room Class Events - iOS
- To receive these events, conform to the
RoomEventListenerprotocol and add the listener withaddEventListener()before you calljoin(). - Every method of
RoomEventListenerhas a default implementation, so implement only the events you need. A method whose signature does not match the protocol exactly still compiles, but it is never called, so copy the signatures from this page. - The SDK calls these methods on the main thread.
- The room holds the listener weakly. Keep a strong reference to the
Roomand to the listener, for example as properties of your view controller.
class RoomViewController: UIViewController {
var room: Room?
func startListening() {
room?.addEventListener(self)
}
}
extension RoomViewController: RoomEventListener {
func onRoomJoined() {
print("Room joined")
}
}
The examples below show each method inside such an extension.
onRoomJoined()
- This event will be emitted when a localParticipant successfully joined the room.
- If you did not pass
participantIdorparticipantNametocreateRoom(), the local participant'sidanddisplayNameare set by now. - It is also emitted after
switchTo(). If you implementonRoomJoined(switchRoomId:), only that variant is called. - It can be emitted again after the SDK rejoins following a lost connection, so make the work you do here safe to repeat. For example, subscribing the same PubSub listener to a topic twice throws
ERROR_INVALID_PARAMETER.
Example
func onRoomJoined() {
print("Room joined")
}
onRoomJoined(switchRoomId:)
- This variant of
onRoomJoined()also tells you whether the join came fromswitchTo().
Event callback parameters
- switchRoomId:
String?- The ID of the room you switched to, ornilfor a normal join.
Example
func onRoomJoined(switchRoomId: String?) {
if let switchRoomId {
print("Switched to room \(switchRoomId)")
} else {
print("Room joined")
}
}
onRoomLeft()
- This event will be emitted when a localParticipant left the room. It tells you why the local participant left.
Event callback parameters
- reason:
LeaveReason- The reason why the participant left. See LeaveReason Enum for all possible values.
Example
func onRoomLeft(reason: LeaveReason) {
print("Room left: \(reason.rawValue) \(reason.message)")
}
onParticipantJoined()
- This event will be emitted when a new participant joined the room.
Event callback parameters
- participant: Participant
Example
func onParticipantJoined(_ participant: Participant) {
print("\(participant.displayName) joined")
}
onParticipantLeft()
- This event will be emitted when a joined participant left the room. It tells you why the participant left.
Event callback parameters
- participant: Participant
- reason:
LeaveReason- The reason why the participant left. See LeaveReason Enum for all possible values.
Example
func onParticipantLeft(_ participant: Participant, reason: LeaveReason) {
print("\(participant.displayName) left: \(reason.message)")
}
onSpeakerChanged()
- This event will be emitted when the active speaker changes.
- If you want to know which participant is actively speaking, then this event will be used.
Event callback parameters
- activeSpeakerId:
String?- The ID of the active speaker, ornilwhen no one is speaking. - You can also read it later with
getActiveSpeakerId().
Example
func onSpeakerChanged(activeSpeakerId: String?) {
print("Active speaker: \(activeSpeakerId ?? "none")")
}
onMicRequested()
- This event will be emitted to the participant
Bwhen any other participantArequests to enable mic of participantB. - On accepting the request, mic of participant
Bwill be enabled.
Event callback parameters
- participantId:
String?- The ID of the participant who sent the request. - accept:
() -> Void- Call it to accept the request. - reject:
() -> Void- Call it to reject the request.
Example
func onMicRequested(participantId: String?, accept: @escaping () -> Void, reject: @escaping () -> Void) {
// Ask the user, then call accept() or reject()
accept()
}
onWebcamRequested()
- This event will be emitted to the participant
Bwhen any other participantArequests to enable webcam of participantB. - On accepting the request, webcam of participant
Bwill be enabled.
Event callback parameters
- participantId:
String?- The ID of the participant who sent the request. - accept:
() -> Void- Call it to accept the request. - reject:
() -> Void- Call it to reject the request.
Example
func onWebcamRequested(participantId: String?, accept: @escaping () -> Void, reject: @escaping () -> Void) {
// Ask the user, then call accept() or reject()
accept()
}
onRecordingStateChanged()
- This event will be emitted when the room's recording status changed.
- All available states are
RECORDING_STARTING,RECORDING_STARTED,RECORDING_STOPPINGandRECORDING_STOPPED.
Event callback parameters
- state:
RecordingState
Example
func onRecordingStateChanged(state: RecordingState) {
switch state {
case .RECORDING_STARTING:
print("recording starting")
case .RECORDING_STARTED:
print("recording started")
case .RECORDING_STOPPING:
print("recording stopping")
case .RECORDING_STOPPED:
print("recording stopped")
@unknown default:
break
}
}
onRecordingStarted()
- This event will be emitted when recording of the room is started.
Example
func onRecordingStarted() {
print("recording started")
}
onRecordingStopped()
- This event will be emitted when recording of the room is stopped.
Example
func onRecordingStopped() {
print("recording stopped")
}
onLivestreamStateChanged()
- This event will be emitted when the room's livestream status changed.
- All available states are
LIVESTREAM_STARTING,LIVESTREAM_STARTED,LIVESTREAM_STOPPINGandLIVESTREAM_STOPPED.
Event callback parameters
- state:
LiveStreamState
Example
func onLivestreamStateChanged(state: LiveStreamState) {
switch state {
case .LIVESTREAM_STARTING:
print("livestream starting")
case .LIVESTREAM_STARTED:
print("livestream started")
case .LIVESTREAM_STOPPING:
print("livestream stopping")
case .LIVESTREAM_STOPPED:
print("livestream stopped")
@unknown default:
break
}
}
onLivestreamStarted()
- This event will be emitted when
RTMPlive stream of the room is started.
Example
func onLivestreamStarted() {
print("livestream started")
}
onLivestreamStopped()
- This event will be emitted when
RTMPlive stream of the room is stopped.
Example
func onLivestreamStopped() {
print("livestream stopped")
}
onHlsStateChanged()
- This event will be emitted when the room's HLS (HTTP Live Streaming) status changed.
- All available states are
HLS_STARTING,HLS_STARTED,HLS_PLAYABLE,HLS_STOPPINGandHLS_STOPPED.
Event callback parameters
- state:
HLSState - hlsUrl:
HLSUrl?- playbackHlsUrl:
String- The HLS URL with playback support. - livestreamUrl:
String- The HLS URL without playback support. - The URLs are available once the state is
HLS_PLAYABLE.
- playbackHlsUrl:
Example
func onHlsStateChanged(state: HLSState, hlsUrl: HLSUrl?) {
switch state {
case .HLS_STARTING:
print("HLS Starting")
case .HLS_STARTED:
print("HLS Started")
case .HLS_PLAYABLE:
print("HLS Playable: \(hlsUrl?.playbackHlsUrl ?? "")")
case .HLS_STOPPING:
print("HLS Stopping")
case .HLS_STOPPED:
print("HLS Stopped")
@unknown default:
break
}
}
onTranscriptionStateChanged()
- This event will be emitted when the room's transcription status is changed.
- All available TranscriptionStates are
TRANSCRIPTION_STARTING,TRANSCRIPTION_STARTED,TRANSCRIPTION_STOPPING,TRANSCRIPTION_STOPPED.
Event callback parameters
- state:
TranscriptionState
Example
func onTranscriptionStateChanged(state: TranscriptionState) {
switch state {
case .TRANSCRIPTION_STARTING:
print("transcription starting")
case .TRANSCRIPTION_STARTED:
print("transcription started")
case .TRANSCRIPTION_STOPPING:
print("transcription stopping")
case .TRANSCRIPTION_STOPPED:
print("transcription stopped")
@unknown default:
break
}
}
onTranscriptionText()
- This event will be emitted when the transcription is received by the SDK.
Event callback parameters
- data:
TranscriptionText- TranscriptionText.participantId:
String- The ID of the participant who spoke. - TranscriptionText.participantName:
String - TranscriptionText.text:
String - TranscriptionText.timestamp:
Int- In milliseconds since epoch. - TranscriptionText.type:
TranscriptionType?-.REALTIMEfor a partial result that can still change,.FULL_SENTENCEfor the settled sentence, ornil.
- TranscriptionText.participantId:
Example
func onTranscriptionText(_ data: TranscriptionText) {
print("transcription text: ", data.text)
print("participant name", data.participantName)
if data.type == .FULL_SENTENCE {
// The text from data.participantId is settled
}
}
onTranslationStateChanged()
- This event will be emitted when the room's realtime translation status is changed, after
startTranslation()orstopTranslation(). - All available states are
TRANSLATION_STARTING,TRANSLATION_STARTED,TRANSLATION_STOPPINGandTRANSLATION_STOPPED.
Event callback parameters
- state:
TranslationState
Example
func onTranslationStateChanged(state: TranslationState) {
switch state {
case .TRANSLATION_STARTING:
print("translation starting")
case .TRANSLATION_STARTED:
print("translation started")
case .TRANSLATION_STOPPING:
print("translation stopping")
case .TRANSLATION_STOPPED:
print("translation stopped")
@unknown default:
break
}
}
onTranslationText()
- This event will be emitted when translated text is received.
- You receive only text in your own translation language. Set it with the
translationLanguageparameter ofcreateRoom()or withchangeTranslationLanguage(). If no translation language is set, this event is not emitted.
Event callback parameters
- data:
TranslationText- TranslationText.participantId:
String- The participant whose speech was translated. - TranslationText.participantName:
String - TranslationText.participantLanguage:
String- The language the participant spoke. - TranslationText.language:
String- The language of the translated text. - TranslationText.text:
String - TranslationText.timestamp:
Double - TranslationText.type:
TranslationType?-.PARTIALwhile the line can still change,.FULLonce it is final, ornil.
- TranslationText.participantId:
Example
func onTranslationText(_ data: TranslationText) {
print("\(data.participantName) (\(data.language)): \(data.text)")
}
onTranslationLanguageChanged()
- This event will be emitted when a participant's translation language changes. It is also emitted for the local participant after
changeTranslationLanguage()takes effect.
Event callback parameters
- participantId:
String- The participant whose language changed. - language:
String- The new language code.
Example
func onTranslationLanguageChanged(participantId: String, language: String) {
print("\(participantId) now receives translations in \(language)")
}
onRoomStateChanged()
- This event will be triggered when state of the room changes.
- It will pass
roomStateas an event callback parameter which will indicate current state of the room. - All available states are:
CONNECTING- The room is connecting.CONNECTED- The room is connected.RECONNECTING- The connection dropped and the SDK is reconnecting. Until it reconnects, most methods throwERROR_ROOM_RECONNECTING.DISCONNECTED- The room connection is closed.FAILED- The room failed to connect, for example whenjoin()fails.
- To know that the local participant has left the room, use
onRoomLeft.
Event callback parameters
- roomState:
RoomState
Example
func onRoomStateChanged(roomState: RoomState) {
switch roomState {
case .CONNECTING:
print("Room is connecting")
case .CONNECTED:
print("Room is connected")
case .RECONNECTING:
print("Room is reconnecting")
case .DISCONNECTED:
print("Room is disconnected")
case .FAILED:
print("Room failed to connect")
@unknown default:
break
}
}
onError()
- This event will be triggered when the SDK reports an error, such as a camera or microphone that fails to open after
enableCam()orunmuteMic(), or an error from the server. - Errors from your own
Roomcalls are thrown asVideoSDKError, so catch them withdo/catch. A call refused before it reaches the server, for example before you join or while the room is reconnecting, is usually only thrown. When the server refuses a join, livestream, HLS, whiteboard, mode change or file upload/fetch request, the error is thrown and also sent here, so show it only once. - It will pass
erroras an event parameter. - For all error codes, see Room Error Codes.
Event callback parameters
- error:
VideoSDKError- code:
Int- The error code. - name:
String- The error name, such asINVALID_TOKEN. - message:
String- A readable reason.
- code:
Example
func onError(error: VideoSDKError) {
switch error {
case .INVALID_TOKEN:
print("Invalid Token")
case .INVALID_ROOM_ID:
print("Invalid room ID")
case .ERROR_CAMERA_ACCESS_DENIED_OR_DISMISSED, .ERROR_CAMERA_PERMISSION_DENIED_BY_OS:
print("Camera access was denied")
default:
print("\(error.name) (\(error.code)): \(error.message)")
}
}
onPinStateChanged()
- This event will be triggered when participant pin state changes.
- It will pass
participantId, state, pinnedByas event parameters. - To read the current pin state of every participant, use
pinnedParticipants.
Event parameters
- participantId:
String - state:
ParticipantPinState-cam: Boolandshare: Booltell you whether the camera and the screen share are pinned. - pinnedBy:
String?- The ID of the participant who changed the pin, ornilif the server did not say.
Example
func onPinStateChanged(participantId: String, state: ParticipantPinState, pinnedBy: String?) {
print("\(participantId) pin state changed: cam \(state.cam), share \(state.share), by \(pinnedBy ?? "unknown")")
}
onParticipantModeChanged()
- This event will be triggered when participant mode changes.
- It will pass
participantId, modeas an event parameter. - All available participant modes are
SEND_AND_RECV,SIGNALLING_ONLYandRECV_ONLY.
Mode.CONFERENCE and Mode.VIEWER were removed in 4.0.0. Use SEND_AND_RECV instead of CONFERENCE, and SIGNALLING_ONLY instead of VIEWER.
Event parameters
- participantId:
String - mode:
Mode
Example
func onParticipantModeChanged(participantId: String, mode: Mode) {
print("\(participantId) is now in \(mode.rawValue) mode")
}
onWhiteboardStarted()
- This event will be triggered when whiteboard is successfully started and it will return the url.
Event callback parameters
- url:
URL
Example
func onWhiteboardStarted(url: URL) {
print("Whiteboard started: \(url)")
}
onWhiteboardStopped()
- This event will be triggered when whiteboard session is stopped.
Example
func onWhiteboardStopped() {
print("Whiteboard stopped")
}
onPausedAllStreams()
- This callback is triggered when all or specified media streams within the room are successfully paused.
Event callback parameters
kind: Specifies the type of media stream that was paused.- Type:
StreamKind? - Possible values:
.AUDIO: Indicates that audio streams have been paused..VIDEO: Indicates that video streams have been paused..SHARE: Indicates that screen-sharing video streams have been pausednil: Indicates that all streams have been paused.
- Type:
Example
func onPausedAllStreams(kind: StreamKind?) {
print("Paused streams: \(String(describing: kind))")
}
onResumedAllStreams()
- This callback is triggered when all or specified media streams within the room are successfully resumed.
Event callback parameters
kind: Specifies the type of media stream that was resumed.- Type:
StreamKind? - Possible values:
.AUDIO: Indicates that audio streams have been resumed..VIDEO: Indicates that video streams have been resumed..SHARE: Indicates that screen-sharing video streams have been resumednil: Indicates that all streams have been resumed.
- Type:
Example
func onResumedAllStreams(kind: StreamKind?) {
print("Resumed streams: \(String(describing: kind))")
}
onEntryRequested()
- This event will be emitted when a participant whose token has the
ask_joinpermission callsjoin(). - It is emitted only to participants whose token has the
allow_joinpermission.
Event callback parameters
- participantId:
String- The ID of the participant who asked to join. - name:
String- The display name of the participant who asked to join. - allow:
() -> Void- Call it to let the participant join. - deny:
() -> Void- Call it to refuse the request.
Example
func onEntryRequested(participantId: String, name: String, allow: @escaping () -> Void, deny: @escaping () -> Void) {
// Ask the user, then call allow() or deny()
allow()
}
onEntryResponded()
- This event will be emitted when a join request is answered.
- It is emitted to participants whose token has the
allow_joinpermission, and to the participant who asked to join.
Event callback parameters
- participantId:
String- The ID of the participant who asked to join. - decision:
EntryDecision?-.ALLOWEDor.DENIED. It isnilif the server sent neither.
Example
func onEntryResponded(participantId: String, decision: EntryDecision?) {
print("Entry request of \(participantId): \(String(describing: decision))")
}
onPresenterChanged()
- This event will be emitted when a participant starts or stops screen sharing.
Event callback parameters
- presenterId:
String?- The ID of the participant who is presenting, ornilwhen no one is presenting. - You can also read it later with
getActivePresenterId().
Example
func onPresenterChanged(presenterId: String?) {
print("Presenter: \(presenterId ?? "none")")
}
onCodecChanged()
- This event will be emitted when the SDK switches your video to another codec because a participant cannot decode the current one. It is used when
codecSwitchEnabledistrueincreateRoom(), which is the default.
Event callback parameters
- info:
CodecChangeInfo- unsupportedRemoteCodec:
VideoCodec- The codec that a participant cannot decode. - currentCodec:
VideoCodec- The codec now in use. - previousCodec:
VideoCodec- The codec used before the switch. - kind:
String- The kind of stream that changed. - causedBy:
Participant?- The participant who cannot decode the codec, if known.
- unsupportedRemoteCodec:
Example
func onCodecChanged(info: CodecChangeInfo) {
print("Video codec changed from \(info.previousCodec.rawValue) to \(info.currentCodec.rawValue)")
}
onExternalCallRinging()
- This event will be emitted when a phone call outside the room starts ringing on the device.
Event callback parameters
- callType:
CallType-.INCOMINGor.OUTGOING.
Example
func onExternalCallRinging(callType: CallType) {
print("External \(callType) call ringing")
}
onExternalCallAnswered()
- This event will be emitted when a phone call outside the room is answered.
Event callback parameters
- callType:
CallType-.INCOMINGor.OUTGOING.
Example
func onExternalCallAnswered(callType: CallType) {
print("External \(callType) call answered")
}
onExternalCallRejected()
- This event will be emitted when a phone call outside the room ends without being answered.
Event callback parameters
- callType:
CallType-.INCOMINGor.OUTGOING.
Example
func onExternalCallRejected(callType: CallType) {
print("External \(callType) call rejected")
}
onExternalCallHangup()
- This event will be emitted when an answered phone call outside the room ends.
Event callback parameters
- callType:
CallType-.INCOMINGor.OUTGOING.
Example
func onExternalCallHangup(callType: CallType) {
print("External \(callType) call ended")
}
onMediaRelayRequestReceived()
- This callback is triggered when a request is received for media relay in the destination room.
Parameters
-
participantId - (String): Specifies the participantId who requested the media relay. -
roomId - (String): Specifies the room from where the media relay request was made. -
displayName - (String): Specifies the displayName of the participant who requested the media relay. -
accept - (() -> Void): Call it to accept the media relay request. -
reject - (() -> Void): Call it to reject the media relay request.
Example
func onMediaRelayRequestReceived(participantId: String, roomId: String, displayName: String, accept: @escaping () -> Void, reject: @escaping () -> Void) {
// Ask the user, then call accept() or reject()
accept()
}
onMediaRelayRequestResponse()
- This callback is triggered when a response is received for media relay request in the source room.
Parameters
-
decision - (RelayDecision?):.ACCEPTEDor.REJECTED. It isnilif the server sent neither. -
decidedBy - (String): Specifies the participantId who responded to the request for the media relay. -
roomId - (String): Specifies the room that responded to the request.
Example
func onMediaRelayRequestResponse(decision: RelayDecision?, decidedBy: String, roomId: String) {
print("Media relay request to \(roomId): \(String(describing: decision)) by \(decidedBy)")
}
onMediaRelayStarted()
- This callback is triggered when the media relay to the destination room successfully starts.
Parameters
roomId - (String): Specifies the room where the media relay started.
Example
func onMediaRelayStarted(roomId: String) {
print("Media relay started to \(roomId)")
}
onMediaRelayStopped()
- This callback is triggered when the media relay to the destination room stops for any reason.
Parameters
-
roomId - (String): Specifies the room where the media relay stopped. -
reason - (String?): Why the relay stopped, as sent by the server, ornilif it sent none.
Example
func onMediaRelayStopped(roomId: String, reason: String?) {
print("Media relay stopped to \(roomId): \(reason ?? "no reason")")
}
onMediaRelayError()
- This callback is triggered when an error occurs during media relay.
Parameters
-
roomId - (String): Specifies the room where the error occurred. -
error - (String): Describes the error.
Example
func onMediaRelayError(roomId: String, error: String) {
print("Media relay error for \(roomId): \(error)")
}
onQualityLimitation()
- This callback is triggered when your call quality is limited by bandwidth, network congestion or CPU, and again when the limitation is resolved.
Parameters
-
type - (QualityLimitationType): Specifies type of quality limitation reason from below enum values:CONGESTION,BANDWIDTH&CPU
-
state - (QualityLimitationState): Specifies the state of quality limitation from below enum values:DETECTED&RESOLVED
-
timestamp - (Int): The time (in milliseconds since epoch) when the event occurred.
Example
func onQualityLimitation(type: QualityLimitationType, state: QualityLimitationState, timestamp: Int) {
print("Quality limitation \(type.rawValue): \(state.rawValue)")
}
onDataReceived()
- This event will be emitted when another participant sends a message with
send().
Event callback parameters
- data:
DataMessage- senderId:
String- The ID of the participant who sent the message. - text:
String?- The text, ornilwhen the sender sent binary data. - data:
Data?- The binary data, ornilwhen the sender sent text. - isBinary:
Bool-truewhen the content is indata. - reliable:
Bool-truewhen the sender sent it reliably. - timestamp:
Int- When the message was received, in milliseconds since epoch.
- senderId:
Example
func onDataReceived(_ data: DataMessage) {
if data.isBinary {
print("Received \(data.data?.count ?? 0) bytes from \(data.senderId)")
} else {
print("\(data.senderId): \(data.text ?? "")")
}
}
Got a Question? Ask us on discord

