Skip to main content
Legacy ringing signalled calls through the Chat SDK: CometChat.initiateCall created the call, a CometChatCallDelegate on the WebSocket told the callee, acceptCall and rejectCall answered, and the app rang the device itself, either with its own PKPushRegistry and CXProvider code or with the Push Notifications SDK 1.0. Ringing now runs on the Calls SDK and the Push Notifications SDK’s Calls product. The Chat SDK’s calling methods are superseded by the Calls SDK and no longer used; a coming Chat SDK release marks them deprecated. This page is the diff. For the full description of the current flow see Ringing; for the push side see Push ringing.

Before you start

Ringing with the Calls SDK is opt-in on the client: moving your app to the Calls SDK 5.1 and Push Notifications SDK 2.0 APIs below is the migration. While some of your users are still on legacy ringing, one dashboard setting lets the two flows call each other; see While some users are still on legacy ringing. This page is for apps that use the SDKs directly. If you use the CometChat UI Kit, its support for this flow comes with a coming UI Kit release; keep legacy ringing until then.

Why it changed

Before and after

Step 1: Update dependencies

Both SDKs are distributed with Swift Package Manager. In Xcode’s package dependencies: CometChatSDK stays for chat; it is no longer used for calls. If your project added these SDKs with CocoaPods, remove their pods from the Podfile and add the packages instead: the Calls SDK 5.1 and Push Notifications SDK 2.0 are not published as pods. A Notification Service Extension links Core and Chat only, never Calls.
  • Keep the Push Notifications capability and Background Modes → Voice over IP (and Remote notifications for chat pushes).
  • Keep NSMicrophoneUsageDescription and NSCameraUsageDescription in Info.plist.
Linking the Calls product turns ringing on. There is no second initializer.

Step 2: Replace the push configuration

appId and region are required in 2.0: the Push SDK registers tokens and brings the Calls SDK up in a process the push started, before your own code has initialized anything. initialize must run in didFinishLaunching, because it creates the PushKit registry and iOS only delivers the VoIP push that launched a killed app when that registry exists by the end of launch.

Step 3: Replace the call delegate

presentCall fires immediately on Answer in every app state, the phone locked included, at most once per session. Return false when you cannot show the call, and the Push SDK ends it.

Step 4: Delete the token code

The Push SDK registers the APNs and VoIP tokens on login by itself. Its own unregister at logout can run after the user’s auth token is gone, so call unregisterTokens and wait for it before you log out (Step 7). Remove:
  • CometChatNotifications.registerPushToken(...) after login and unregisterPushToken(...) before logout
  • The VoIP token handling in your own pushRegistry(_:didUpdate:for:)
Keep forwarding the APNs device token with CometChatPushNotifications.shared.registerDeviceToken(deviceToken) in application(_:didRegisterForRemoteNotificationsWithDeviceToken:); the VoIP token is captured by the Calls product. If your app must keep its own PKPushRegistry, see Owning PushKit yourself.

Step 5: Delete the app-side ringing

Everything in this list is now done by the Push SDK. Remove it, or it will fight the SDK’s ring (two CallKit calls, two providers that cannot end each other’s calls, a busy reject sent on top of the SDK’s).
  • CometChat.addCallListener(...) / CometChat.calldelegate and the onIncomingCallReceived handler
  • The incoming-call screen, banner or alert you showed from it, and your own ringtone for incoming calls
  • Your PKPushRegistry and PKPushRegistryDelegate, CXProvider, CXProviderDelegate, CXCallController and the CallManager that tied them to CometChat (the pattern the earlier VoIP Calling guide described)
  • Any AVAudioSession.setActive(true) in CallKit callbacks: CallKit owns the call’s audio session, and activating it yourself causes one-way audio on lock-screen answers
  • The “already in a call → reject with busy” check
  • With Push SDK 1.0: foregroundCallPresentation, CometChatIncomingCallView / incomingCallStyle, notifyCallsSDKReady()

Step 6: Rewrite the call code

Caller screen, before and after

Callee screen, before and after

Step 7: Change the logout

While some users are still on legacy ringing

Your users don’t all update at once, so during the rollout one CometChat app has devices on both flows. A device’s flow comes from its push registration: a device on the Calls SDK 5.1 and Push Notifications SDK 2.0 receives only the call-initiated push, and a device still on legacy ringing keeps receiving the legacy call events. To let users on the two flows call each other, turn on Connect legacy ringing in the CometChat dashboard under Voice & Video Calls → Settings. CometChat then also sends calls made on this flow as legacy call events, so devices on either flow ring for calls from the other.
  • Turn it on before the first users update, and leave it on while any version of your apps still in use rings the legacy way.
  • It can’t be turned off from the dashboard.
  • The six legacy call events (ongoing, cancelled, rejected, unanswered, busy and ended) are under Show legacy in Notifications → Settings → Call Preferences. They only reach devices on legacy ringing.

What users will notice

  • Calls ring through CallKit with the app killed and from the lock screen, with no app code on the ring path.
  • The caller sees “Ringing…” once the callee’s phone is reached, and the call screen closes when the call is declined or missed (from the Call Logs status, or the ring timer).
  • The callee stops ringing after 45 seconds, and the caller’s screen closes on its own timer.
  • Missed calls appear in the Phone app’s Recents.
  • A call during a call is call waiting (End & Accept ends the current call, Decline sends busy), not an automatic reject.
  • The microphone and camera prompt appears after Answer the first time, on the device that answers; on a locked phone it waits for the unlock.
  • Outgoing calls appear in Recents too, and survive an incoming cellular call.

Checklist

  • CometChatCallsSDK 5.1, Push SDK 2.0 Core + Calls products added; the Notification Service Extension links Core + Chat only
  • Push Notifications capability, Background Modes → Voice over IP, microphone and camera usage strings
  • initialize(config:) runs in didFinishLaunching with appId, region and providerId
  • The delegate adopts CometChatPushNotificationsCallsDelegate and is kept alive; presentCall(_:) presents and joins at once
  • Manual token registration and notifyCallsSDKReady() removed
  • CometChat.addCallListener, your own PushKit / CallKit code, incoming UI, ringtone, busy check and setActive calls removed
  • initiateCall sets the session type in sessionSettings, built with a new SessionSettingsBuilder()
  • Caller listens on the prepared session and joins only on onParticipantJoined; runs a 45 s ring timer
  • Hang-up uses leave(); no CometChat.endCall
  • Logout awaits unregisterTokens, then logs out of the Calls SDK as well
  • ensureRingReady runs after sign-in and anything other than .ready is shown to the user
  • Connect legacy ringing is on in the dashboard if some users stay on legacy ringing during the rollout
  • Tested on a device: ring with the app killed and the phone locked, decline, cancel, no answer, call during a call, logout while ringing