CallKit – how to configure it?

CallKit – how to configure it?
iOS 10 offers many new features. One of them is CallKit, the framework which allows our application to seamlessly integrate with the user interface of a phone. CallKit may be used in applications to allow users to receive incoming calls and perform outgoing calls with the phone-provided UI. VoIP call can be muted or suspended. It is also possible to make video calls.

Preparing the project

The first step is to prepare receiving VoIP notifications.

Background modes - Voice over IP

Configuring VoIP notifications

To configure the application to receive notifications, import framework PushKit to our AppDelegate file and create an object PKPushRegistry. Be sure to set the delegate of the newly created object as self, and set its type as VoIP:

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey : Any]? = nil) -> Bool {
        let pushRegistry = PKPushRegistry(queue: DispatchQueue.main)
        pushRegistry.delegate = self
        pushRegistry.desiredPushTypes = [.voIP]

        return true

Functions used for storing credentials on the server for the active user and processing pushs are:

func pushRegistry(_ registry: PKPushRegistry, didUpdate credentials: PKPushCredentials, forType type: PKPushType) {
            //Store push credentials on server for the active user.

func pushRegistry(_ registry: PKPushRegistry, didReceiveIncomingPushWith payload: PKPushPayload, forType type: PKPushType) {

Supporting received notifications

The final step is to parse the data received from the function didReceiveIncomingPushWith, which, among other things, can wake the phone from the state of being locked.

func pushRegistry(_ registry: PKPushRegistry, didReceiveIncomingPushWith payload: PKPushPayload, forType type: PKPushType) {
        guard type == .voIP else { return }

        if let uuidString = payload.dictionaryPayload["UUID"] as? String,
           let handle = payload.dictionaryPayload["handle"] as? String,
           let hasVideo = payload.dictionaryPayload["hasVideo"] as? Bool,
           let uuid = UUID(uuidString: uuidString)
             // Handle incoming call

Setting up CallKit

The first step is to create a class to handle incoming calls by extending the class CXProviderDelegate.

final class ProviderDelegate: NSObject, CXProviderDelegate {
    private let provider: CXProvider

The next step is to configure the provider.

static var providerConfiguration: CXProviderConfiguration {
        let localizedName = NSLocalizedString("APPLICATION_NAME", comment: "name")
        let providerConfiguration = CXProviderConfiguration(localizedName: localizedName)

        providerConfiguration.supportsVideo = true

        providerConfiguration.maximumCallsPerCallGroup = 1

        providerConfiguration.supportedHandleTypes = [.phoneNumber]

        if let iconMaskImage = UIImage(named: "wideo") {
            providerConfiguration.iconTemplateImageData = UIImagePNGRepresentation(iconMaskImage)

        providerConfiguration.ringtoneSound = "Ringtone.caf"

        return providerConfiguration

The last step is to provide an initializer, add the reportIncomingCall function responsible for the transfer of an incoming call to the system and to add providerDidReset function which is called when the provider is restarted.

init() {
        provider = CXProvider(configuration: type(of: self).providerConfiguration)
        provider.setDelegate(self, queue: nil)

func reportIncomingCall(uuid: UUID, handle: String, hasVideo: Bool = false, completion: ((NSError?) -> Void)? = nil) {
        // Construct a CXCallUpdate describing the incoming call, including the caller.
        let update = CXCallUpdate()
        update.remoteHandle = CXHandle(type: .phoneNumber, value: handle)
        update.hasVideo = hasVideo

        // Report the incoming call to the system
        provider.reportNewIncomingCall(with: uuid, update: update) { error in
            completion?(error as? NSError)

func providerDidReset(_ provider: CXProvider) {
        print("Provider did reset")
            End any ongoing calls if the provider resets, and remove them from the app's list of calls,
            since they are no longer valid.

This is only an introduction, and if you would like to learn more about this, I recommend reading There is a lot of information and a sample application there.

Learn more

Swift switch or, the fun conditions are

I would like you to get acquainted with a switch conditional statement in Swift, using the rubber duck method. I assume that you already know the concept of the switch statement, therefore, I will show you what is new in Swift. Let's play with conditions!
Read more

Speech Recognizer API – what do you need to know?

In iOS 10 we can use SFSpeechRecognizer API, which allows transcription in real-time or using pre-recorded audio files. The outcome of such transcription is not only a text, but also alternative interpretations of the audio, length of spoken words and level of accuracy of recognized words (range 0.0 - 1.0). API allows for the analysis of more than 50 languages. Using SFSpeechRecognizer API in an application is trivial, it boils down to four steps.
Read more

Searching application content in iOS in a nutshell

Today, I will talk about one of the frameworks added in iOS 9: Core Spotlight . API allows you to add content to spotlight search engine, so that, for example, an application used for watching movies allows for adding movies, actors, directors and reacting if users select an item, so that we can move them to the desired location within the application.
Read more

Project estimation

Check out how we use our knowledge in practice, and make your project with us.

Why choose us?

Logo Mobile Trends Awards

Mobile Trends Awards 2017

Nomination in M-commerce category


clients reviews

Clutch logo
Logo Legalni bukmacherzy

Legal Bookmakers Award 2019

Best Mobile App


projects in portfolio