Skip to main content
This guide covers migrating from Calls SDK v4 to v5 for iOS.

Drop-in Compatibility

Calls SDK v5 is a drop-in replacement for v4. All v4 APIs are preserved as deprecated methods that internally delegate to the new v5 implementations. You can update the dependency version and your existing code will compile and run without changes.
# CocoaPods — update your Podfile
-pod 'CometChatCallsSDK', '~> 4.0'
+pod 'CometChatCallsSDK', '~> 5.0'
// Swift Package Manager — update your package dependency version to 5.x
If you’re using CometChat UI Kits, simply updating the Calls SDK version is sufficient. The UI Kit will continue to work with v5 through the deprecated compatibility layer.

Why Migrate to v5 APIs?

While v4 APIs will continue to work, migrating to v5 APIs gives you:
  • Granular event listeners — 5 focused listener protocols instead of one monolithic CallsEventsDelegate
  • CallSession singleton for cleaner session control — all actions on a single object instead of scattered static methods
  • Dedicated login() method — the Calls SDK now handles its own authentication instead of depending on the Chat SDK’s auth token or REST APIs
  • Strongly-typed enumsAudioModeType, CallType, LayoutType, CameraFacing instead of raw strings

Initialization

No changes required. The init API is the same in v5.
let callAppSettings = CallAppSettings()
callAppSettings.set(appId: "APP_ID")
callAppSettings.set(region: "REGION")

CometChatCalls(callsAppSettings: callAppSettings, onSuccess: { success in
    // Initialized
}, onError: { error in
    // Handle error
})

Authentication

In v4, the Calls SDK had no dedicated authentication step. It relied on the Chat SDK’s auth token (CometChat.getUserAuthToken()) or a REST API to obtain an auth token, which you then passed manually to generateToken(authToken:sessionID:onSuccess:onError:). v5 introduces its own login() method. After calling login(), the SDK caches the auth token internally, so you no longer need to pass it around to other API calls.
// No dedicated Calls SDK login — relied on Chat SDK for auth token
let authToken = CometChat.getUserAuthToken()

// Had to pass authToken manually
CometChatCalls.generateToken(authToken: authToken as NSString?,
                             sessionID: sessionID as NSString?,
                             onSuccess: { token in
    // Use token to start session
}, onError: { error in })
Call CometChatCalls.login() once after your user authenticates (e.g., right after CometChat.login() succeeds). The SDK stores the auth token internally, so subsequent calls like generateToken() and joinSession() use it automatically without you having to pass it.

Session Settings

CallSettingsBuilder and PresentationSettingsBuilder are replaced by SessionSettingsBuilder. The builder methods have been renamed for clarity.
let callSettings = CometChatCalls.callSettingsBuilder
    .setIsAudioOnly(true)
    .setDefaultLayout(true)
    .setEndCallButtonDisable(false)
    .setMuteAudioButtonDisable(false)
    .setPauseVideoButtonDisable(false)
    .setSwitchCameraButtonDisable(false)
    .setAudioModeButtonDisable(false)
    .setShowRecordingButton(true)
    .setStartAudioMuted(false)
    .setStartVideoMuted(false)
    .setDefaultAudioMode("SPEAKER")
    .setMode("DEFAULT")
    .setStartRecordingOnCallStart(false)
    .setDelegate(self)
    .build()

Builder Method Mapping

v4 Methodv5 MethodNotes
setIsAudioOnly(true)setType(.audio)Use .video for video calls
setDefaultLayout(bool)hideControlPanel(!bool) + hideHeaderPanel(!bool)Inverted logic
setEndCallButtonDisable(bool)hideLeaveSessionButton(bool)Same logic
setMuteAudioButtonDisable(bool)hideToggleAudioButton(bool)Same logic
setPauseVideoButtonDisable(bool)hideToggleVideoButton(bool)Same logic
setSwitchCameraButtonDisable(bool)hideSwitchCameraButton(bool)Same logic
setAudioModeButtonDisable(bool)hideAudioModeButton(bool)Same logic
setShowRecordingButton(bool)hideRecordingButton(!bool)Inverted logic
setStartAudioMuted(bool)startAudioMuted(bool)Same logic
setStartVideoMuted(bool)startVideoPaused(bool)Same logic
setDefaultAudioMode("SPEAKER")setAudioMode(.speaker)Enum instead of string
setMode("DEFAULT")setLayout(.tile)Enum instead of string
setStartRecordingOnCallStart(bool)enableAutoStartRecording(bool)Same logic
setAvatarMode(string)RemovedNo longer applicable
setEnableVideoTileClick(bool)RemovedNo longer applicable
setEnableDraggableVideoTile(bool)RemovedNo longer applicable
setDelegate(delegate)Use CallSession listenersSee Events section

Joining a Session

startSession() is replaced by joinSession().
// Step 1: Generate token with auth token
CometChatCalls.generateToken(authToken: authToken as NSString?,
                             sessionID: sessionID as NSString?,
                             onSuccess: { token in
    // Step 2: Start session with token string
    CometChatCalls.startSession(callToken: token ?? "",
                                callSetting: callSettings,
                                view: callView,
                                onSuccess: { message in
        // Session started
    }, onError: { error in })
}, onError: { error in })
Key differences:
  • v5 generateToken() no longer requires the authToken parameter (uses cached token from login())
  • v5 offers a convenience overload that takes sessionID directly and handles token generation internally
  • Parameter name changed from view to container

Session Control (Actions)

In v4, session actions were static methods on CometChatCalls. In v5, they’re instance methods on CallSession.shared.
CometChatCalls.endSession()
CometChatCalls.switchCamera()
CometChatCalls.audioMuted(true)
CometChatCalls.videoPaused(true)
CometChatCalls.setAudioMode(mode: "SPEAKER")
CometChatCalls.enterPIPMode()
CometChatCalls.exitPIPMode()
CometChatCalls.startRecording()
CometChatCalls.stopRecording()

Action Method Mapping

v4 Static Methodv5 CallSession Method
CometChatCalls.endSession()callSession.leaveSession()
CometChatCalls.switchCamera()callSession.switchCamera()
CometChatCalls.audioMuted(true)callSession.muteAudio()
CometChatCalls.audioMuted(false)callSession.unmuteAudio()
CometChatCalls.videoPaused(true)callSession.pauseVideo()
CometChatCalls.videoPaused(false)callSession.resumeVideo()
CometChatCalls.setAudioMode(mode:)callSession.setAudioMode(_:)
CometChatCalls.enterPIPMode()callSession.enablePictureInPictureLayout()
CometChatCalls.exitPIPMode()callSession.disablePictureInPictureLayout()
CometChatCalls.startRecording()callSession.startRecording()
CometChatCalls.stopRecording()callSession.stopRecording()
CometChatCalls.switchToVideoCall()Removed

Event Listeners

This is the biggest improvement in v5. The single CallsEventsDelegate protocol is replaced by 5 focused listener protocols.

v4: Single Monolithic Delegate

class MyViewController: UIViewController, CallsEventsDelegate {

    func setupCallEvents() {
        // Set via builder
        CometChatCalls.callSettingsBuilder.setDelegate(self).build()
    }

    func onCallEnded() { }
    func onCallEndButtonPressed() { }
    func onSessionTimeout() { }
    func onUserJoined(rtcUser: RTCUser) { }
    func onUserLeft(rtcUser: RTCUser) { }
    func onUserListChanged(rtcUsers: [RTCUser]) { }
    func onAudioModeChanged(mode: [CallAudioMode]) { }
    func onCallSwitchedToVideo(callSwitchedInfo: CallSwitchRequestInfo) { }
    func onUserMuted(rtcMutedUser: RTCMutedUser) { }
    func onRecordingToggled(recordingInfo: RTCRecordingInfo) { }
}

v5: Focused Listener Protocols

let callSession = CallSession.shared

// Session lifecycle events
class MySessionListener: SessionStatusListener {
    func onSessionJoined() { }
    func onSessionLeft() { }
    func onSessionTimedOut() { }
    func onConnectionLost() { }
    func onConnectionRestored() { }
    func onConnectionClosed() { }
}
callSession.addSessionStatusListener(mySessionListener)

// Participant events (replaces onUserJoined, onUserLeft, onUserListChanged, onUserMuted)
class MyParticipantListener: ParticipantEventListener {
    func onParticipantJoined(participant: Participant) { }
    func onParticipantLeft(participant: Participant) { }
    func onParticipantListChanged(participants: [Participant]) { }
    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 onParticipantStartedRecording(participant: Participant) { }
    func onParticipantStoppedRecording(participant: Participant) { }
    func onDominantSpeakerChanged(participant: Participant) { }
}
callSession.addParticipantEventListener(myParticipantListener)

// Media state events (replaces onAudioModeChanged, onRecordingToggled)
class MyMediaListener: MediaEventsListener {
    func onAudioMuted() { }
    func onAudioUnMuted() { }
    func onVideoPaused() { }
    func onVideoResumed() { }
    func onRecordingStarted() { }
    func onRecordingStopped() { }
    func onAudioModeChanged(audioModeType: AudioModeType) { }
    func onCameraFacingChanged(cameraFacing: CameraFacing) { }
}
callSession.addMediaEventsListener(myMediaListener)

// Button click events (replaces onCallEndButtonPressed)
class MyButtonListener: ButtonClickListener {
    func onLeaveSessionButtonClicked() { }
    func onToggleAudioButtonClicked() { }
    func onToggleVideoButtonClicked() { }
    func onSwitchCameraButtonClicked() { }
    func onRaiseHandButtonClicked() { }
    func onRecordingToggleButtonClicked() { }
}
callSession.addButtonClickListener(myButtonListener)

// Layout events
class MyLayoutListener: LayoutListener {
    func onCallLayoutChanged(layoutType: LayoutType) { }
    func onPictureInPictureLayoutEnabled() { }
    func onPictureInPictureLayoutDisabled() { }
}
callSession.addLayoutListener(myLayoutListener)
v5 listeners use weak references internally, so they are automatically cleaned up when the listener object is deallocated. You can also explicitly remove listeners using removeSessionStatusListener(_:), removeParticipantEventListener(_:), etc.

Event Mapping

v4 Eventv5 Listenerv5 Event
onCallEnded()SessionStatusListeneronSessionLeft()
onCallEndButtonPressed()ButtonClickListeneronLeaveSessionButtonClicked()
onSessionTimeout()SessionStatusListeneronSessionTimedOut()
onUserJoined(rtcUser:)ParticipantEventListeneronParticipantJoined(participant:)
onUserLeft(rtcUser:)ParticipantEventListeneronParticipantLeft(participant:)
onUserListChanged(rtcUsers:)ParticipantEventListeneronParticipantListChanged(participants:)
onAudioModeChanged(mode:)MediaEventsListeneronAudioModeChanged(audioModeType:)
onCallSwitchedToVideo(callSwitchedInfo:)Removed
onUserMuted(rtcMutedUser:)ParticipantEventListeneronParticipantAudioMuted(participant:)
onRecordingToggled(recordingInfo:)MediaEventsListeneronRecordingStarted() / onRecordingStopped()

New Events in v5

These events are only available with the v5 listener APIs:
ListenerEventDescription
SessionStatusListeneronConnectionLost()Network interrupted
SessionStatusListeneronConnectionRestored()Network restored
SessionStatusListeneronConnectionClosed()Connection permanently closed
ParticipantEventListeneronParticipantVideoResumed()Participant turned camera on
ParticipantEventListeneronParticipantVideoPaused()Participant turned camera off
ParticipantEventListeneronParticipantHandRaised()Participant raised hand
ParticipantEventListeneronParticipantHandLowered()Participant lowered hand
ParticipantEventListeneronParticipantStartedScreenShare()Participant started screen share
ParticipantEventListeneronParticipantStoppedScreenShare()Participant stopped screen share
ParticipantEventListeneronDominantSpeakerChanged()Active speaker changed
MediaEventsListeneronCameraFacingChanged()Camera switched front/back
ButtonClickListenerVarious button eventsIndividual button click tracking
LayoutListeneronCallLayoutChanged()Layout type changed
LayoutListeneronPictureInPictureLayoutEnabled/Disabled()PiP state changed

Call Logs

The CallLogsRequest API is unchanged. The only difference is that auth is now handled by CometChatCalls.login() instead of passing the auth token manually.

Deprecated Classes Summary

These classes still exist in v5 for backward compatibility but are deprecated:
Deprecated ClassReplacement
CallSettingsSessionSettingsBuilder.SessionSettings
CallSettingsBuilderSessionSettingsBuilder
PresentationSettingsSessionSettingsBuilder.SessionSettings
PresentationSettingsBuilderSessionSettingsBuilder
CallsEventsDelegate5 focused listeners on CallSession
RTCRecordingInfoMediaEventsListener callbacks
CallSwitchRequestInfoRemoved (no replacement)