Overview
This section demonstrates how to start a call session in an iOS application. Previously known as Direct Calling.
Before you begin, we strongly recommend you read the calling setup guide.
If you want to implement a complete calling experience with ringing functionality (incoming/outgoing call UI), follow the Ringing guide first. Once the call is accepted, return here to start the call session.
Generate Call Token
A call token is required for secure access to a call session. Each token is unique to a specific session and user combination, ensuring that only authorized users can join the call.
You can generate the token just before starting the call, or generate and store it ahead of time based on your use case.
Use the generateToken() method to create a call token:
var callToken: GenerateToken?
let sessionId = "UNIQUE_SESSION_ID" // Random or from Call object in ringing flow
let authToken = CometChat.getUserAuthToken() // Logged in user auth token
CometChatCalls.generateToken(authToken: authToken as NSString, sessionID: sessionId) { token in
self.callToken = token
} onError: { error in
print("Token generation failed: \(String(describing: error?.errorDescription))")
}
| Parameter | Description |
|---|
sessionId | The unique session ID. In ringing flow, this is available in the Call object. For standalone calls, generate a random unique string. |
authToken | The logged-in user’s auth token from CometChat.getUserAuthToken(). |
Start Call Session
Use the startSession() method to join a call session. This method requires a call token (generated in the previous step) and a CallSettings object that configures the call UI and behavior.
The CallSettings class configures the call UI and behavior. Use CallSettingsBuilder to create a CallSettings instance with the following required parameters:
| Parameter | Description |
|---|
view | A UIView where the calling UI will be rendered |
callToken | The GenerateToken object received from generateToken() onSuccess |
guard let callToken = self.callToken else { return }
let callSettings = CometChatCalls.CallSettingsBuilder
.setDefaultLayout(true)
.setIsAudioOnly(false)
.setDelegate(self)
.build()
CometChatCalls.startSession(callToken: callToken, callSetting: callSettings, view: callView) { success in
print("Call session started successfully")
} onError: { error in
print("Start session failed: \(String(describing: error?.errorDescription))")
}
Call Settings
Configure the call experience using the following CallSettingsBuilder methods:
| Method | Description |
|---|
setDefaultLayout(Bool) | Enables or disables the default call UI layout with built-in controls. true shows the default layout. Default: true |
setIsAudioOnly(Bool) | Sets whether the call is audio-only or audio-video. true for audio-only. Default: false |
setIsSingleMode(Bool) | Enables single participant mode. |
setShowSwitchToVideoCall(Bool) | Shows or hides the switch to video call button. |
setEnableVideoTileClick(Bool) | Enables or disables click interactions on video tiles. Default: true |
setEnableDraggableVideoTile(Bool) | Enables or disables drag functionality for video tiles in Spotlight mode. Default: true |
setEndCallButtonDisable(Bool) | Shows or hides the end call button. Default: false (shown) |
setShowRecordingButton(Bool) | Shows or hides the recording button. Default: false |
setSwitchCameraButtonDisable(Bool) | Shows or hides the switch camera button. Default: false (shown) |
setMuteAudioButtonDisable(Bool) | Shows or hides the mute audio button. Default: false (shown) |
setPauseVideoButtonDisable(Bool) | Shows or hides the pause video button. Default: false (shown) |
setAudioModeButtonDisable(Bool) | Shows or hides the audio mode selection button. Default: false (shown) |
setStartAudioMuted(Bool) | Starts the call with the microphone muted. Default: false |
setStartVideoMuted(Bool) | Starts the call with the camera turned off. Default: false |
setMode(DisplayModes) | Sets the call UI layout mode. Available: .default, .single, .spotlight. Default: .default |
setAvatarMode(AvatarMode) | Sets avatar display mode. Available: .circle, .square, .fullscreen. Default: .circle |
setDefaultAudioMode(AudioMode) | Sets the initial audio output device. Available: SPEAKER, EARPIECE, BLUETOOTH, HEADPHONES |
setIdleTimeoutPeriod(Int) | Sets idle timeout in seconds. Warning appears 60 seconds before auto-termination. Default: 180. v4.1.1+ |
setDelegate(self) | Sets the delegate to receive call events. |
Call Listeners
The CallsEventsDelegate protocol provides real-time callbacks for call session events, including participant changes, call state updates, and error conditions.
To receive call events, conform to CallsEventsDelegate and set the delegate in CallSettingsBuilder using setDelegate(self).
extension ViewController: CallsEventsDelegate {
func onCallEnded() {
// Call ended, close the calling screen
}
func onSessionTimeout() {
// Session timed out due to inactivity
}
func onCallEndButtonPressed() {
// User pressed end call button
}
func onUserJoined(rtcUser: RTCUser) {
// A participant joined the call
}
func onUserLeft(rtcUser: RTCUser) {
// A participant left the call
}
func onUserListChanged(rtcUsers: [RTCUser]) {
// Participant list updated
}
func onAudioModeChanged(mode: [AudioMode]) {
// Available audio devices changed
}
func onCallSwitchedToVideo(callSwitchedInfo: CallSwitchRequestInfo) {
// Call upgraded from audio to video
}
func onUserMuted(rtcMutedUser: RTCMutedUser) {
// A participant's mute state changed
}
func onRecordingToggled(recordingInfo: RTCRecordingInfo) {
// Recording started or stopped
}
}
Events
| Event | Description |
|---|
onCallEnded() | Invoked when the call session terminates for a 1:1 call. Both participants receive this callback. |
onSessionTimeout() | Invoked when the call is auto-terminated due to inactivity (default: 180 seconds). v4.1.1+ |
onCallEndButtonPressed() | Invoked when the local user taps the end call button. For ringing flow, call CometChat.endCall(). For standalone, call CometChatCalls.endSession(). |
onUserJoined(rtcUser: RTCUser) | Invoked when a remote participant joins. |
onUserLeft(rtcUser: RTCUser) | Invoked when a remote participant leaves. |
onUserListChanged(rtcUsers: [RTCUser]) | Invoked whenever the participant list changes. |
onAudioModeChanged(mode: [AudioMode]) | Invoked when available audio devices change. |
onCallSwitchedToVideo(callSwitchedInfo: CallSwitchRequestInfo) | Invoked when an audio call is upgraded to video. |
onUserMuted(rtcMutedUser: RTCMutedUser) | Invoked when a participant’s mute state changes. |
onRecordingToggled(recordingInfo: RTCRecordingInfo) | Invoked when call recording starts or stops. |
End Call Session
Ending a call session properly is essential to release media resources (camera, microphone, network connections) and update call state across all participants.
Ringing Flow
When using the Ringing flow, you must coordinate between the CometChat Chat SDK and the Calls SDK to properly terminate the call.
The Ringing flow requires calling methods from both the Chat SDK (CometChat.endCall()) and the Calls SDK (CometChatCalls.endSession()) to ensure proper call termination.
User who initiates the end call:
When the user presses the end call button, the onCallEndButtonPressed() callback is triggered. Inside this callback, call CometChat.endCall(). On success, call CometChat.clearActiveCall() and CometChatCalls.endSession().
func onCallEndButtonPressed() {
CometChat.endCall(sessionID: sessionId) { call in
CometChat.clearActiveCall()
CometChatCalls.endSession()
// Close the calling screen
} onError: { error in
print("End call failed: \(String(describing: error?.errorDescription))")
}
}
Remote participant (receives onCallEnded() callback):
func onCallEnded() {
CometChat.clearActiveCall()
CometChatCalls.endSession()
// Close the calling screen
}
Session Only Flow
When using the Session Only flow (without ringing), you only need to call the Calls SDK method to end the session.
func onCallEndButtonPressed() {
CometChatCalls.endSession()
// Close the calling screen
}
Methods
These methods are available for performing custom actions during an active call session. Use them to build custom UI controls or implement specific behaviors based on your use case.
These methods can only be called when a call session is active.
Switch Camera
Toggles between the front and rear camera during a video call.
CometChatCalls.switchCamera()
[CometChatCalls switchCamera];
Mute Audio
Controls the local audio stream transmission.
// Mute audio
CometChatCalls.audioMuted(true)
// Unmute audio
CometChatCalls.audioMuted(false)
// Mute audio
[CometChatCalls audioMuted:YES];
// Unmute audio
[CometChatCalls audioMuted:NO];
Pause Video
Controls the local video stream transmission.
// Pause video
CometChatCalls.videoPaused(true)
// Resume video
CometChatCalls.videoPaused(false)
// Pause video
[CometChatCalls videoPaused:YES];
// Resume video
[CometChatCalls videoPaused:NO];
Set Audio Mode
Routes the audio output to a specific device.
CometChatCalls.setAudioMode(AudioMode(mode: "SPEAKER"))
[CometChatCalls setAudioModeWithMode:@"SPEAKER"];
Enter PIP Mode
Enters Picture-in-Picture mode.
CometChatCalls.enterPIPMode()
[CometChatCalls enterPIPMode];
Exit PIP Mode
Exits Picture-in-Picture mode.
CometChatCalls.exitPIPMode()
[CometChatCalls exitPIPMode];
Switch To Video Call
Upgrades an ongoing audio call to a video call.
CometChatCalls.switchToVideoCall()
[CometChatCalls switchToVideoCall];
Start Recording
Starts recording the call session.
CometChatCalls.startRecording()
[CometChatCalls startRecording];
Stop Recording
Stops an ongoing call recording.
CometChatCalls.stopRecording()
[CometChatCalls stopRecording];
End Call
Terminates the current call session and releases all media resources.
CometChatCalls.endSession()
[CometChatCalls endSession];