Handle call session events to build responsive UIs. The SDK provides five event listener protocols to monitor session status, participant activities, media changes, button clicks, and layout changes.
Get CallSession Instance
The CallSession is a singleton that manages the active call. All event listener registrations and session control methods are accessed through this instance.
let callSession = CallSession. shared
CallSession *callSession = [CallSession shared];
Remember to remove listeners when your view controller is deallocated to prevent memory leaks. Use removeSessionStatusListener, removeParticipantEventListener, etc.
Session Events
Monitor the call session lifecycle including join/leave events and connection status.
class CallViewController : UIViewController , SessionStatusListener {
override func viewDidLoad () {
super . viewDidLoad ()
CallSession. shared . addSessionStatusListener ( self )
}
deinit {
CallSession. shared . removeSessionStatusListener ( self )
}
func onSessionJoined () {
// Successfully connected to the session
}
func onSessionLeft () {
// Left the session
navigationController ? . popViewController ( animated : true )
}
func onSessionTimedOut () {
// Session ended due to inactivity
navigationController ? . popViewController ( animated : true )
}
func onConnectionLost () {
// Network interrupted, attempting reconnection
}
func onConnectionRestored () {
// Connection restored after being lost
}
func onConnectionClosed () {
// Connection permanently closed
navigationController ? . popViewController ( animated : true )
}
}
@interface CallViewController () <SessionStatusListener>
@end
@implementation CallViewController
- (void)viewDidLoad {
[super viewDidLoad];
[[CallSession shared] addSessionStatusListener:self];
}
- (void)dealloc {
[[CallSession shared] removeSessionStatusListener:self];
}
- (void)onSessionJoined {
// Successfully connected to the session
}
- (void)onSessionLeft {
// Left the session
[self.navigationController popViewControllerAnimated:YES];
}
- (void)onSessionTimedOut {
// Session ended due to inactivity
[self.navigationController popViewControllerAnimated:YES];
}
- (void)onConnectionLost {
// Network interrupted, attempting reconnection
}
- (void)onConnectionRestored {
// Connection restored after being lost
}
- (void)onConnectionClosed {
// Connection permanently closed
[self.navigationController popViewControllerAnimated:YES];
}
@end
Event Description onSessionJoined()Successfully connected and joined the session onSessionLeft()Left the session via leaveSession() or was removed onSessionTimedOut()Session ended due to inactivity timeout onConnectionLost()Network interrupted, SDK attempting reconnection onConnectionRestored()Connection restored after being lost onConnectionClosed()Connection permanently closed, cannot reconnect
Participant Events
Monitor participant activities including join/leave, audio/video state, hand raise, screen sharing, and recording.
class CallViewController : UIViewController , ParticipantEventListener {
override func viewDidLoad () {
super . viewDidLoad ()
CallSession. shared . addParticipantEventListener ( self )
}
deinit {
CallSession. shared . removeParticipantEventListener ( self )
}
func onParticipantJoined ( participant : Participant) {
// A participant joined the call
}
func onParticipantLeft ( participant : Participant) {
// A participant left the call
}
func onParticipantListChanged ( participants : [Participant]) {
// Participant list updated
}
func onParticipantAudioMuted ( participant : Participant) {}
func onParticipantAudioUnmuted ( participant : Participant) {}
func onParticipantVideoPaused ( participant : Participant) {}
func onParticipantVideoResumed ( participant : Participant) {}
func onParticipantHandRaised ( participant : Participant) {}
func onParticipantHandLowered ( participant : Participant) {}
func onParticipantStartedScreenShare ( participant : Participant) {}
func onParticipantStoppedScreenShare ( participant : Participant) {}
func onParticipantStartedRecording ( participant : Participant) {}
func onParticipantStoppedRecording ( participant : Participant) {}
func onDominantSpeakerChanged ( participant : Participant) {}
}
@interface CallViewController () <ParticipantEventListener>
@end
@implementation CallViewController
- (void)viewDidLoad {
[super viewDidLoad];
[[CallSession shared] addParticipantEventListener:self];
}
- (void)dealloc {
[[CallSession shared] removeParticipantEventListener:self];
}
- (void)onParticipantJoinedWithParticipant:(Participant *)participant {
// A participant joined the call
}
- (void)onParticipantLeftWithParticipant:(Participant *)participant {
// A participant left the call
}
- (void)onParticipantListChangedWithParticipants:(NSArray<Participant *> *)participants {
// Participant list updated
}
// Other callbacks...
@end
Event Parameter Description onParticipantJoinedParticipantA participant connected to the call onParticipantLeftParticipantA participant disconnected from the call onParticipantListChanged[Participant]Participant list updated onParticipantAudioMutedParticipantA participant muted their microphone onParticipantAudioUnmutedParticipantA participant unmuted their microphone onParticipantVideoPausedParticipantA participant turned off their camera onParticipantVideoResumedParticipantA participant turned on their camera onParticipantHandRaisedParticipantA participant raised their hand onParticipantHandLoweredParticipantA participant lowered their hand onParticipantStartedScreenShareParticipantA participant started screen sharing onParticipantStoppedScreenShareParticipantA participant stopped screen sharing onParticipantStartedRecordingParticipantA participant started recording onParticipantStoppedRecordingParticipantA participant stopped recording onDominantSpeakerChangedParticipantThe active speaker changed
Monitor your local media state changes including audio/video status, recording, and device changes.
class CallViewController : UIViewController , MediaEventsListener {
override func viewDidLoad () {
super . viewDidLoad ()
CallSession. shared . addMediaEventsListener ( self )
}
deinit {
CallSession. shared . removeMediaEventsListener ( self )
}
func onAudioMuted () {
// Your microphone was muted
}
func onAudioUnMuted () {
// Your microphone was unmuted
}
func onVideoPaused () {
// Your camera was turned off
}
func onVideoResumed () {
// Your camera was turned on
}
func onRecordingStarted () {
// Call recording started
}
func onRecordingStopped () {
// Call recording stopped
}
func onScreenShareStarted () {}
func onScreenShareStopped () {}
func onAudioModeChanged ( audioModeType : AudioModeType) {
// Audio output device changed
}
func onCameraFacingChanged ( cameraFacing : CameraFacing) {
// Camera switched between front and back
}
}
@interface CallViewController () <MediaEventsListener>
@end
@implementation CallViewController
- (void)viewDidLoad {
[super viewDidLoad];
[[CallSession shared] addMediaEventsListener:self];
}
- (void)dealloc {
[[CallSession shared] removeMediaEventsListener:self];
}
- (void)onAudioMuted {
// Your microphone was muted
}
- (void)onAudioUnMuted {
// Your microphone was unmuted
}
- (void)onVideoPaused {
// Your camera was turned off
}
- (void)onVideoResumed {
// Your camera was turned on
}
- (void)onRecordingStarted {
// Call recording started
}
- (void)onRecordingStopped {
// Call recording stopped
}
- (void)onAudioModeChangedWithAudioModeType:(AudioModeType)audioModeType {
// Audio output device changed
}
- (void)onCameraFacingChangedWithCameraFacing:(CameraFacing)cameraFacing {
// Camera switched between front and back
}
// Other callbacks...
@end
Event Parameter Description onAudioMuted- Your microphone was muted onAudioUnMuted- Your microphone was unmuted onVideoPaused- Your camera was turned off onVideoResumed- Your camera was turned on onRecordingStarted- Call recording started onRecordingStopped- Call recording stopped onScreenShareStarted- You started screen sharing onScreenShareStopped- You stopped screen sharing onAudioModeChangedAudioModeTypeAudio output device changed onCameraFacingChangedCameraFacingCamera switched between front and back
Value Description .speakerAudio routed through device loudspeaker .earpieceAudio routed through phone earpiece .bluetoothAudio routed through connected Bluetooth device .headphonesAudio routed through wired headphones
Value Description .FRONTFront-facing (selfie) camera is active .BACKRear-facing (main) camera is active
Intercept UI button clicks from the default call interface to add custom behavior or analytics.
class CallViewController : UIViewController , ButtonClickListener {
override func viewDidLoad () {
super . viewDidLoad ()
CallSession. shared . addButtonClickListener ( self )
}
deinit {
CallSession. shared . removeButtonClickListener ( self )
}
func onLeaveSessionButtonClicked () {
// Leave button tapped
}
func onToggleAudioButtonClicked () {
// Mute/unmute button tapped
}
func onToggleVideoButtonClicked () {
// Video on/off button tapped
}
func onSwitchCameraButtonClicked () {}
func onRaiseHandButtonClicked () {}
func onShareInviteButtonClicked () {}
func onChangeLayoutButtonClicked () {}
func onParticipantListButtonClicked () {}
func onChatButtonClicked () {}
func onRecordingToggleButtonClicked () {}
}
@interface CallViewController () <ButtonClickListener>
@end
@implementation CallViewController
- (void)viewDidLoad {
[super viewDidLoad];
[[CallSession shared] addButtonClickListener:self];
}
- (void)dealloc {
[[CallSession shared] removeButtonClickListener:self];
}
- (void)onLeaveSessionButtonClicked {
// Leave button tapped
}
- (void)onToggleAudioButtonClicked {
// Mute/unmute button tapped
}
- (void)onToggleVideoButtonClicked {
// Video on/off button tapped
}
// Other callbacks...
@end
Event Description onLeaveSessionButtonClickedLeave/end call button was tapped onToggleAudioButtonClickedMute/unmute button was tapped onToggleVideoButtonClickedVideo on/off button was tapped onSwitchCameraButtonClickedCamera switch button was tapped onRaiseHandButtonClickedRaise hand button was tapped onShareInviteButtonClickedShare/invite button was tapped onChangeLayoutButtonClickedLayout change button was tapped onParticipantListButtonClickedParticipant list button was tapped onChatButtonClickedIn-call chat button was tapped onRecordingToggleButtonClickedRecording toggle button was tapped
Button click events fire before the SDK’s default action executes. Use these to add custom logic alongside default behavior.
Layout Events
Monitor layout changes including layout type switches and Picture-in-Picture mode transitions.
class CallViewController : UIViewController , LayoutListener {
override func viewDidLoad () {
super . viewDidLoad ()
CallSession. shared . addLayoutListener ( self )
}
deinit {
CallSession. shared . removeLayoutListener ( self )
}
func onCallLayoutChanged ( layoutType : LayoutType) {
// Layout changed (TILE, SPOTLIGHT)
}
func onParticipantListVisible () {
// Participant list panel opened
}
func onParticipantListHidden () {
// Participant list panel closed
}
func onPictureInPictureLayoutEnabled () {
// Entered PiP mode
}
func onPictureInPictureLayoutDisabled () {
// Exited PiP mode
}
}
@interface CallViewController () <LayoutListener>
@end
@implementation CallViewController
- (void)viewDidLoad {
[super viewDidLoad];
[[CallSession shared] addLayoutListener:self];
}
- (void)dealloc {
[[CallSession shared] removeLayoutListener:self];
}
- (void)onCallLayoutChangedWithLayoutType:(LayoutType)layoutType {
// Layout changed (TILE, SPOTLIGHT)
}
- (void)onParticipantListVisible {
// Participant list panel opened
}
- (void)onParticipantListHidden {
// Participant list panel closed
}
- (void)onPictureInPictureLayoutEnabled {
// Entered PiP mode
}
- (void)onPictureInPictureLayoutDisabled {
// Exited PiP mode
}
@end
Event Parameter Description onCallLayoutChangedLayoutTypeCall layout changed onParticipantListVisible- Participant list panel was opened onParticipantListHidden- Participant list panel was closed onPictureInPictureLayoutEnabled- Call entered Picture-in-Picture mode onPictureInPictureLayoutDisabled- Call exited Picture-in-Picture mode
Value Description Best For .tileGrid layout with equally-sized tiles Group discussions, team meetings .spotlightLarge view for active speaker, small tiles for others Presentations, one-on-one calls
Clear All Listeners
Remove all registered listeners at once. Useful when cleaning up resources.
CallSession. shared . clearAllListeners ()
[[CallSession shared] clearAllListeners];