Introduction to CallKit
Introduction to CallKit
CallKit iOS, Audio call support in iOS app, Video Call support in iOS app
In this blog, i am focusing only on CallKit framework, in next blog i will be covering Intent extension and PushKit framework. Lets start!
Life on iOS wasn’t always perfect for VoIP app developers.Luckily, Apple introduced CallKit in iOS 10 to change all that!
How do VoIP apps work today?
Overview
CallKit lets you integrates system services(Bluetooth, Siri,
Face time, Phone App) with your VoIP Service. It provides the
calling interface of phone app and your VoIP Service need to
take care of back-end communication.
For incoming and
outgoing calls, CallKit displays the same interfaces as the
Phone app, giving your app a more native look and feel.
CallKit
lets you responds appropriately to system-level behaviors such
as Do Not Disturb, Low network connectivity.
In addition to handling calls, you can provide a Call Directory app extension to provide caller ID information and a list of blocked numbers associated with your service.
Basic CallKit Concepts
Now that you know what
CallKit
is all
about, let’s take a closer look at a few fundamental concepts
you’ll need in order to understand and make use of it.
- CXProvider Create single instance of CXProvider and use throughout your VoIP app, its object is responsible for reporting out-of-band notifications that occur to the system.Initialize a new provider instance with the supplied configuration.
let provider: CXProvider = CXProvider(configuration: type(of: self).providerConfiguration)
-
CXProviderConfiguration The app’s provider configuration, representing its CallKit
capabilities, you can configure below properties:
- Localized name of the provider, ex: Name of application
- ringtoneSound, Name of resource in app’s bundle to play as ringtone for incoming call, ex: “MyRingtone.aif”
- MaximumCallGroups , Default is 2
- MaximumCallsPerCallGroup, Default is 5
- Whether this provider’s calls should be included in the system’s Recents list at the end of each call (includesCallsInRecents).
- SupportsVideo, whether VoIP service supports video or not, Default isNO
- SupportedHandleTypes (CXHandleType), ex: supportedHandleTypes = [.phoneNumber]
static var providerConfiguration: CXProviderConfiguration {
let localizedName = NSLocalizedString(“APPLICATION_NAME”, comment: “Name of application”)
let providerConfiguration = CXProviderConfiguration(localizedName: localizedName)
providerConfiguration.supportsVideo = true
providerConfiguration.maximumCallsPerCallGroup = 1
providerConfiguration.supportedHandleTypes = [.phoneNumber]
if let iconMaskImage = UIImage(named: “myMask”) {
providerConfiguration.iconTemplateImageData = UIImagePNGRepresentation(iconMaskImage)
}
providerConfiguration.ringtoneSound = “Ringtone.aif”
return providerConfiguration
}
-
CXProviderDelegate protocol defines a set of methods that are called by an
object that represents a telephony provider when the provider
begins or resets, a transaction is requested, an action is
performed, or an audio session changes its activation state.
let’s take a closer look :
- Handling provider events, Called when the provider begins or provider is reset.
- Determining the executions of transactions,Called when a transaction is executed by a call controller.
- Handling call actions, Called when the provider performs the specified start/answer/end/hold/muted/group/DTMF (dual tone multifrequency) call action
- Handling changes to audio session activation state, called when the provider’s audio session is activated/deactivated.
Incoming Calls
When a PushKit notification indicates an incoming call, you generate an appropriate action. CallKit handles the action by presenting the system interface for answering the call.
When an incoming call is allowed by the system and approved by
the user, the provider sends
provider(_:perform:)
to its delegate (as mentioned above in this blog). The
provider’s delegate calls the
fulfill()
method
to indicate that the action was successfully performed. To
indicate that the call connected at a time other than the
current time, you can instead call the
fulfill(withDateConnected:)
.
//local function which reportNewIncomingCall function of CXProvider class to report it to the system
func reportIncomingCall(uuid: UUID, handle: String, hasVideo: Bool = false, completion: ((Error?) -> Void)? = nil)
//Signal to the system that the action has been successfully performed.In delegate callbacks like below
action.fulfill()
In your local
reportIncomingCall function, Construct a CXCallUpdate describing the incoming call,
including the caller.CXCallUpdate
objects are used by the system to communicate changes to calls
over time.
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
}
Only add incoming call to the app’s list of calls if the call was allowed (i.e. there was no error), Since calls may be “denied” for various legitimate reasons. See CXErrorCodeIncomingCallError for more detail.
Outgoing Calls
Start outgoing calls with a call controller, and handle subsequent interactions with your provider delegate.
CXCallController objects interact with call by performing actions.You can
request that one or more actions be performed in a single
CXTransaction
object using the
request(_:completion:)
method.
Call activity may come from phone app or from any other system services, We need to provide interface such that our app can handle that events.
These above functions need to override for providing the start
call interface to system services.
When the telephony
provider receives an incoming call or the user starts an
outgoing call, the other caller is identified by a
CXHandle
object. For a caller identified by a phone number, the handle
type is
CXHandle.HandleType.phoneNumber
and the value is a sequence of digits. For a caller identified
by an email address, the handle type is
CXHandle.HandleType.emailAddress
and the value is an email address. For a caller identified in
any other way, the handle type is
CXHandle.HandleType.generic
and the value typically follows some domain-specific format,
such as a username, numeric ID, or URL.
CXStartCallAction
is a concrete subclass of
CXCallAction
.
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.
CXTransaction An object that contains zero or more action objects to be performed by a call controller. it addAction such as CXStartCallAction ,CXEndCallAction, CXSetHeldCallAction.
Hope you like this article, Please ❤️ to recommend this post to others 😊. Let me know your feedback. :)
References: