Skip to main content
Version: 4.x.x

Room Class Events - iOS

  • To receive these events, conform to the RoomEventListener protocol and add the listener with addEventListener() before you call join().
  • Every method of RoomEventListener has 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 Room and 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 participantId or participantName to createRoom(), the local participant's id and displayName are set by now.
  • It is also emitted after switchTo(). If you implement onRoomJoined(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 from switchTo().

Event callback parameters​

  • switchRoomId: String? - The ID of the room you switched to, or nil for 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​

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​

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, or nil when 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 B when any other participant A requests to enable mic of participant B.
  • On accepting the request, mic of participant B will 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 B when any other participant A requests to enable webcam of participant B.
  • On accepting the request, webcam of participant B will 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_STOPPING and RECORDING_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_STOPPING and LIVESTREAM_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 RTMP live stream of the room is started.

Example​

func onLivestreamStarted() {
print("livestream started")
}

onLivestreamStopped()​

  • This event will be emitted when RTMP live 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_STOPPING and HLS_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.

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? - .REALTIME for a partial result that can still change, .FULL_SENTENCE for the settled sentence, or nil.

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() or stopTranslation().
  • All available states are TRANSLATION_STARTING, TRANSLATION_STARTED, TRANSLATION_STOPPING and TRANSLATION_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 translationLanguage parameter of createRoom() or with changeTranslationLanguage(). 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? - .PARTIAL while the line can still change, .FULL once it is final, or nil.

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 roomState as 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 throw ERROR_ROOM_RECONNECTING.
    • DISCONNECTED - The room connection is closed.
    • FAILED - The room failed to connect, for example when join() 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() or unmuteMic(), or an error from the server.
  • Errors from your own Room calls are thrown as VideoSDKError, so catch them with do / 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 error as 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 as INVALID_TOKEN.
    • message: String - A readable reason.

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, pinnedBy as event parameters.
  • To read the current pin state of every participant, use pinnedParticipants.

Event parameters​

  • participantId: String
  • state: ParticipantPinState - cam: Bool and share: Bool tell you whether the camera and the screen share are pinned.
  • pinnedBy: String? - The ID of the participant who changed the pin, or nil if 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, mode as an event parameter.
  • All available participant modes are SEND_AND_RECV, SIGNALLING_ONLY and RECV_ONLY.
note

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 paused
      • nil: Indicates that all streams have been paused.

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 resumed
      • nil: Indicates that all streams have been resumed.

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_join permission calls join().
  • It is emitted only to participants whose token has the allow_join permission.

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_join permission, and to the participant who asked to join.

Event callback parameters​

  • participantId: String - The ID of the participant who asked to join.
  • decision: EntryDecision? - .ALLOWED or .DENIED. It is nil if 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, or nil when 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 codecSwitchEnabled is true in createRoom(), 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.

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 - .INCOMING or .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 - .INCOMING or .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 - .INCOMING or .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 - .INCOMING or .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?): .ACCEPTED or .REJECTED. It is nil if 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, or nil if 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, or nil when the sender sent binary data.
    • data: Data? - The binary data, or nil when the sender sent text.
    • isBinary: Bool - true when the content is in data.
    • reliable: Bool - true when the sender sent it reliably.
    • timestamp: Int - When the message was received, in milliseconds since epoch.

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