Using CallKit to create a VoIP App

CallKit Framework Overview

CallKit is a new framework and is available in iOS 10 and later. Used to implement VoIP functionality, call blocking, and identification in your app. Apps can use CallKit to receive incoming calls and outgoing calls using the native call UI.

VoIP Push Notification

A VoIP app lets the user make and receive phone calls using an Internet connection instead of the device’s cellular service. Because a VoIP app relies heavily on the network, it’s no surprise that making calls result in high energy use. When not in active use, however, a VoIP app should be completely idle to conserve energy.
For more information about VoIP push notification and PushKit, see Voice over Internet Protocol (VoIP) ( and PushKit Framework (

Step 1: Prepare To Receive VoIP Push Notification

Now open your application target.Choose capabilities and select ‘Voice over IP’ under background modes


Step 2: Configure VoIP Push Notification

To configure your app to receive VoIP push notifications, import to the PushKit framework in your app delegate. Create a PKPushRegistry object, set its delegate to self, and register to receive VoIP pushes.

Implement a delegate method to handle updated push credentials. If your app receives both standard push notifications and VoIP pushes, then your app will receive two separate push tokens. Both tokens must be passed to the server to receive notifications.

Step 3: Handle Received Notification

Payload data which you will receive in didReceiveIncomingPushWith method and this method is called even in Background mode.

Configure CallKit Framework

Create a “ProviderDelegate” class to handle incoming calls action by extending CXProviderDelegate.

Step 1: Configure CallKit capabilities

Configure your call by representing its CallKit capabilities. A CXProviderConfiguration object controls the native call UI for incoming and outgoing calls, including a localized name for the provider, the ringtone to be played for incoming calls, and the icon to be displayed during calls. A provider configuration can also set the maximum number of call groups and a number of calls in a single call group, determine whether to use emails and/or phone numbers as handles and specify whether a video is supported.

Step 2: Initialise ProviderDelegate

Initialise CXProvider class with the type and provider configuration which we have just declared.

Create a method named reportIncomingCall with some basic parameters to update CXCallUpdate by describing the CXHandle type and value like in type you can give options like .phoneNumber, EmailAddress and Generic and a provider will report new Incoming Call to CXProvider.

Using the information provided by the external notification, the app creates a UUID and a CXCallUpdate ( object to uniquely identify the call and the caller and passes them both to the provider using reportNewIncomingCall(with: update: completion:) ( method.

Step 3 : Handling CXProviderDelegate

Called when the provider has been reset. Delegates must respond to this callback by cleaning up all internal call state (disconnecting communication channels, releasing network resources, etc.). This callback can be treated as a request to end all calls without the need to respond to any actions.

The CXCallAction subclass is an abstract class that represents an action associated with a CXCall Object. The CallKit framework provides several concrete CXCallAction subclasses to represent actions such as answering a call and putting a call on hold. Each instance of CXAction is uniquely identified by a UUID, which is generated on initialization. An action also tracks whether it has been completed or not.

Step 4 : Accept call using CXAnswerCallAction

The Call is connected, the system sends provider(_:perform:) to the provider delegate. In your implementation, the delegate is responsible for configuring an AVAudioSession and calling fulfill() on the action when finished.

Step 5 : End call using CXEndCallAction

When the user initiates an outgoing call the provider sends provider(_: perform:) to its delegate. The Provider’s delegate calls the fulfill() method to indicate that the action was successfully performed.

Step 6 : Hold the call using CXSetHeldCallAction

When a caller places a call on hold, callers are unable to communicate with one another until the holding caller removes the call from hold. Placing a call on hold doesn’t end the call.

When the user or the system places a call on hold the provider sends provider(_: perform:) to its delegate. The Provider’s delegate calls the fulfill() method to indicate that the action was successfully performed.

Step 7: Initiate call from AppDelegate

AppDelegate you can call a displayIncomingCall method inside didReceiveIncomingPushWith PKPushRegitryDelegate method to initialise your call.


Source Code:


Use of VoIP and CallKit framework in your app you’ll need to give the proper description of the usage of both feature otherwise they may reject your metadata at the time of app Review.

More reference

  1. CallKit Framework ( )
  2. Enhancing VoIP Apps with CallKit ( )

Sandeep Joshi iOS Team Lead

I’m Sandeep Joshi - an iOS developer at Yudiz Solutions Pvt. Ltd. - a leading iPhone App Development company. I am ambitious and intensely interested in what I do. You'll quickly find that I do not merely develop software - I develop highly maintainable, elegant code that will save you enormous sums in the long run.

Comments are closed.