Skip to main content
Quick Reference for AI Agents & Developers
  • Requires: CometChat SDK and UI Kit both configured
  • Implementation: Handle notification tap in AppDelegate or SceneDelegate
  • Parse payload: Extract call session ID from notification payload
  • Launch: Present CometChatIncomingCall view controller
  • Related: Ringing · Push Notifications · UI Kit
This guide helps you to launch an incoming call screen from the UI Kit library on receiving an incoming call notification.
CometChat SDK & UI Kit both need to be configured before launching the call screen.

Step 1. Process push notification payload and grab Call object

To present an incoming call screen, firstly you will need a Call object. You can grab this from the push notification payload itself of incoming call notification. You need to call CometChat.processMessage() method to process push notification payload.
 func userNotificationCenter(_ center: UNUserNotificationCenter,
                    didReceive response: UNNotificationResponse,
                    withCompletionHandler completionHandler: @escaping () -> Void) {
        
        if let userInfo = response.notification.request.content.userInfo as? [String : Any], let messageObject = userInfo["message"] as? [String:Any] {
           print("didReceive: \(userInfo)")
          if let baseMessage = CometChat.processMessage(messageObject).0 {
            switch baseMessage.messageCategory {
            case .message:
                print("Message Object Received: \(String(describing: (baseMessage as? TextMessage)?.stringValue()))")
                
            case .action: break
            case .call: break
            case .custom: break
            @unknown default: break
            }
          }
        }
        completionHandler()
      }
userInfo Dictionary Structure:
ParameterTypeDescription
message[String: Any]Message dictionary containing call details. See message Dictionary below
aps[String: Any]Apple Push Notification Service payload. See aps Dictionary below
message Dictionary:
ParameterTypeDescription
idIntUnique message identifier. Example: 98765
categoryStringMessage category. Example: "call"
typeStringCall type. Example: "audio" or "video"
sessionIdStringUnique call session ID. Example: "v1.us.call_session_xyz789"
sender[String: Any]Sender user details. See sender Dictionary below
receiverStringReceiver UID. Example: "cometchat-uid-2"
receiverTypeStringReceiver type. Example: "user"
statusStringCall status. Example: "initiated"
sentAtIntUnix timestamp when call was initiated. Example: 1699800000
sender Dictionary:
ParameterTypeDescription
uidStringSender’s unique ID. Example: "cometchat-uid-1"
nameStringSender’s display name. Example: "Andrew Joseph"
avatarStringSender’s avatar URL. Example: "https://example.com/avatar.png"
statusStringUser online status. Example: "online"
roleStringUser role. Example: "default"
lastActiveAtIntLast active timestamp. Example: 1699799000
aps Dictionary:
ParameterTypeDescription
alert[String: Any]Alert content. See alert Dictionary below
badgeIntBadge count. Example: 1
soundStringNotification sound. Example: "default"
mutable-contentIntEnables notification modification. Example: 1
alert Dictionary:
ParameterTypeDescription
titleStringNotification title. Example: "Incoming Call"
bodyStringNotification body. Example: "Andrew Joseph is calling..."
Method Signature:
ParameterTypeDescription
Input[String: Any]Push notification message dictionary
Returns(BaseMessage?, CometChatException?)Tuple containing parsed message or error
Return Tuple Structure:
IndexTypeDescription
0BaseMessage?Parsed message object (Call when category is “call”). See Call Object below
1CometChatException?Error object if parsing fails. nil on success
Call Object Properties:
ParameterTypeDescription
idIntMessage ID. Example: 98765
muidStringMessage unique ID. Example: "muid_abc123"
messageCategoryMessageCategoryCategory enum. Example: .call
messageTypeMessageTypeType enum. Example: .audio or .video
sessionIDString?Call session identifier. Example: "v1.us.call_session_xyz789"
callStatusCallStatusCurrent call status. Example: .initiated
callTypeCallTypeType of call. Example: .audio or .video
senderUserSender user object. See User Object below
receiverUserReceiver user object. See User Object below
receiverTypeReceiverTypeType of receiver. Example: .user
sentAtIntUnix timestamp. Example: 1699800000
readAtIntRead timestamp. Example: 0 (unread)
deliveredAtIntDelivery timestamp. Example: 0 (not delivered)
sender User Object:
ParameterTypeDescription
uidStringUser’s unique ID. Example: "cometchat-uid-1"
nameStringUser’s display name. Example: "Andrew Joseph"
avatarString?User’s avatar URL. Example: "https://example.com/avatar.png"
statusUserStatusOnline status. Example: .online
roleStringUser role. Example: "default"
lastActiveAtIntLast active timestamp. Example: 1699799000
receiver User Object:
ParameterTypeDescription
uidStringUser’s unique ID. Example: "cometchat-uid-2"
nameStringUser’s display name. Example: "Jane Smith"
avatarString?User’s avatar URL. Example: "https://example.com/avatar2.png"
statusUserStatusOnline status. Example: .offline
roleStringUser role. Example: "default"
CallStatus Enum Values:
ValueDescription
.initiatedCall has been initiated
.ongoingCall is in progress
.unansweredCall was not answered
.rejectedCall was rejected
.busyReceiver was busy
.cancelledCall was cancelled
.endedCall has ended
CallType Enum Values:
ValueDescription
.audioAudio-only call
.videoVideo call

Step 2. Launch call screen (Method 1)

You can directly launch the view controller from the app delegate once you receive Call Object.
  if let call = baseMessage as? Call {
      DispatchQueue.main.async {
      let call = CometChatIncomingCall()
      call.modalPresentationStyle = .custom
      call.setCall(call: call)
     if let window = self.window, let rootViewController = window.rootViewController      {
     var currentController = rootViewController
     while let presentedController = currentController.presentedViewController {
     currentController = presentedController
     }
      if (!call.isViewLoaded && (call.view.window != nil)) {
     currentController.present(call, animated: true, completion: nil)
      }
     }
   }
 }
CometChatIncomingCall View Controller Setup:
ParameterTypeDescription
modalPresentationStyleUIModalPresentationStylePresentation style for the view controller. Example: .custom
setCall(call:)CallMethod to set the Call object. See Call Object below
UIModalPresentationStyle Values:
ValueDescription
.customCustom presentation style (recommended for incoming call)
.fullScreenFull screen presentation
.overFullScreenOverlay on full screen
Call Object Properties Used for Display:
ParameterTypeDescription
sessionIDStringSession ID for the call. Example: "v1.us.call_session_xyz789"
callTypeCallTypeAudio or video indicator. Example: .audio
callStatusCallStatusCurrent status. Example: .initiated
senderUserCaller information displayed on screen. See sender Object below
sender User Object (Displayed on Incoming Call Screen):
ParameterTypeDescription
uidStringCaller’s unique ID. Example: "cometchat-uid-1"
nameStringCaller name displayed on screen. Example: "Andrew Joseph"
avatarString?Caller avatar URL displayed on screen. Example: "https://example.com/avatar.png"
statusUserStatusOnline status. Example: .online
View Controller Presentation Flow:
StepActionDescription
1Initializelet call = CometChatIncomingCall()
2Set stylecall.modalPresentationStyle = .custom
3Set call datacall.setCall(call: callObject)
4PresentcurrentController.present(call, animated: true)
If you are facing any difficulties while launching the Call Screen from App Delegate, then you can use another method.

Step 2. Launch call screen (Method 2)

You can launch the call screen from your base view controller instead of launching it from the App Delegate. This method uses NotificationCenter to trigger and present Call Screen.
  1. In this method you need to fire notification after you receive Call Object.
  2. In Notification’s user info you can pass Call Object to that desired notification.

Trigger notification from App Delegate

if let call = baseMessage as? Call {
  DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
 NotificationCenter.default.post(name: NSNotification.Name(rawValue: "didReceivedIncomingCall"), object: nil, userInfo: ["call":call])
   }
}
NotificationCenter.default.post() Method Parameters:
ParameterTypeDescription
nameNSNotification.NameNotification identifier name. Example: NSNotification.Name(rawValue: "didReceivedIncomingCall")
objectAny?Sender object (typically nil). Example: nil
userInfo[AnyHashable: Any]?Dictionary containing call data. See userInfo Dictionary below
userInfo Dictionary Structure:
ParameterTypeDescription
callCallThe Call object to pass to the observer. See Call Object below
Call Object in userInfo:
ParameterTypeDescription
idIntMessage ID. Example: 98765
sessionIDStringCall session ID. Example: "v1.us.call_session_xyz789"
callTypeCallTypeType of call. Example: .audio
callStatusCallStatusCurrent status. Example: .initiated
senderUserCaller details. See sender Object below
receiverUserReceiver details
receiverTypeReceiverTypeReceiver type. Example: .user
sentAtIntUnix timestamp. Example: 1699800000
sender User Object:
ParameterTypeDescription
uidStringCaller’s unique ID. Example: "cometchat-uid-1"
nameStringCaller’s display name. Example: "Andrew Joseph"
avatarString?Caller’s avatar URL. Example: "https://example.com/avatar.png"
statusUserStatusOnline status. Example: .online
Notification Dispatch Flow:
StepActionDescription
1DelayDispatchQueue.main.asyncAfter(deadline: .now() + 0.5)
2PostNotificationCenter.default.post(...)
3ObserveBaseViewController receives notification
4HandleSelector method extracts Call and presents UI
  1. On the other hand, you need to observe for the above notification in your base view controller
  1. Base view controller is a controller that launches immediately after the app delegate.
  2. Base view controller should be present to observe the notification when notification fires.
  3. If the view controller is not present in the memory when a new notification receives, then it won’t launch Call Screen.

Observe notification in Base View Controller

class BaseViewController : UIViewController {
  
  override func viewDidLoad() {
    NotificationCenter.default.addObserver(self, selector:#selector(self.didReceivedIncomingCall(_:)), name: NSNotification.Name(rawValue: "didReceivedIncomingCall"), object: nil)
  }
}

Add selector method & Launch call screen

 @objc func didReceivedIncomingCall(_ notification: NSNotification) {
        if let currentCall = notification.userInfo?["call"] as? Call {
            DispatchQueue.main.async {
              let call = CometChatIncomingCall()
              call.modalPresentationStyle = .custom
              call.setCall(call: currentcall)
              self.present(call, animated: true, completion: nil)
            }
        }
 }
NSNotification Object Structure:
ParameterTypeDescription
nameNSNotification.NameNotification identifier. Example: "didReceivedIncomingCall"
objectAny?Sender object. Example: nil
userInfo[AnyHashable: Any]?Dictionary containing call data. See userInfo Dictionary below
userInfo Dictionary:
ParameterTypeDescription
callCallThe Call object from notification. See Call Object below
Call Object Properties:
ParameterTypeDescription
idIntMessage ID. Example: 98765
sessionIDStringCall session ID. Example: "v1.us.call_session_xyz789"
callTypeCallTypeType of call. Example: .audio or .video
callStatusCallStatusCurrent status. Example: .initiated
senderUserCaller user object. See sender Object below
receiverUserReceiver user object
receiverTypeReceiverTypeReceiver type. Example: .user
sentAtIntUnix timestamp. Example: 1699800000
sender User Object:
ParameterTypeDescription
uidStringCaller UID. Example: "cometchat-uid-1"
nameStringCaller name. Example: "Andrew Joseph"
avatarString?Caller avatar URL. Example: "https://example.com/avatar.png"
statusUserStatusOnline status. Example: .online
roleStringUser role. Example: "default"
lastActiveAtIntLast active timestamp. Example: 1699799000
CometChatIncomingCall Presentation Configuration:
ParameterTypeDescription
modalPresentationStyleUIModalPresentationStylePresentation style. Example: .custom
setCall(call:)CallMethod to set Call object for display
Selector Method Flow:
StepActionDescription
1Extractnotification.userInfo?["call"] as? Call
2DispatchDispatchQueue.main.async { ... }
3Initializelet call = CometChatIncomingCall()
4Configurecall.setCall(call: currentCall)
5Presentself.present(call, animated: true)