iOS Calling UI SDK
The iOS Calling UI SDK wraps Apple's native calling infrastructure to deliver a full incoming-call screen experience in your iOS app with minimal code. When a VoIP push arrives, the SDK presents the familiar iOS system-level calling UI — the same one users see for regular phone calls — and routes accept, reject, hold, and end actions back to your app via callback delegates. Combined with the iOS UI Kit, you can enable complete app-to-app audio/video calling in under five minutes.
Ships as Enx_CallKit_iOS.framework. Install via CocoaPods or add manually to your Xcode project.
The SDK's core class is EnxCallKit. You create a single instance in the class where
your app handles incoming VoIP push notifications, then call reportIncomingCall to
trigger the system calling UI. The SDK handles the full UI lifecycle and calls back your delegate
methods when the user interacts with the screen.
When loading the calling UI, you must wrap the operation in an iOS background task to ensure the system gives your app enough time to present the screen before being suspended.
Before integrating the iOS Calling UI SDK, ensure:
- VoIP background mode enabled — In Xcode, go to your target's Signing & Capabilities tab and add the Background Modes capability. Enable Voice over IP. This allows your app to receive PushKit VoIP notifications while in the background and launch the calling UI.
- Notification service in place — EnableX does not provide a push notification service. You must integrate Apple PushKit (VoIP push) with your server to deliver incoming-call signals to the device. The SDK cannot present its UI without an incoming push trigger.
Via CocoaPods
Open your Podfile and add the SDK pod, then install:
pod 'Enx_CallKit_iOS'
cd /path/to/your-project/
pod install
Manual Installation
- Download
Enx_CallKit_iOS.framework_1.0.3.zipusing the button above and unzip it. - In Xcode, open your project navigator and drag
Enx_CallKit_iOS.frameworkinto the Frameworks, Libraries, and Embedded Content section of your target. - Set the embed option to Embed & Sign.
1. Import and Initialise
Go to the class where you receive VoIP push notifications (typically your
PKPushRegistryDelegate implementation). Import the framework and create an
EnxCallKit instance:
import Enx_CallKit_iOS
class CallNotificationHandler: NSObject, PKPushRegistryDelegate, EnxCallKitDelegate {
var callManager: EnxCallKit?
func setup() {
callManager = EnxCallKit(self)
// self: sets the callback delegate
}
}
2. Report an Incoming Call
When a VoIP push arrives, use reportIncomingCall to present the system calling UI.
Wrap it in a background task so iOS does not suspend the app before the UI appears:
func pushRegistry(_ registry: PKPushRegistry,
didReceiveIncomingPushWith payload: PKPushPayload,
for type: PKPushType,
completion: @escaping () -> Void) {
// Begin a background task — iOS must not suspend the app during UI presentation
let bgTask = UIApplication.shared.beginBackgroundTask(expirationHandler: nil)
let callerName = payload.dictionaryPayload["callerName"] as? String ?? "Unknown"
let hasVideo = payload.dictionaryPayload["hasVideo"] as? Bool ?? false
callManager?.reportIncomingCall(
uuid: UUID(),
callerName: callerName,
hasVideo: hasVideo
) { _ in
// End the background task once the calling UI has loaded
UIApplication.shared.endBackgroundTask(bgTask)
completion()
}
}
3. End a Call Programmatically
To dismiss the calling UI from your code (for example when a session ends on the remote side),
call endCall(). This closes the system calling screen immediately:
callManager?.endCall()
Implement the EnxCallKitDelegate protocol in the class you passed as self
during initialisation. The SDK calls these methods based on user interaction with the calling screen:
| Callback | When it fires | What to do |
|---|---|---|
func callAnswer() |
User taps Accept | Connect to the EnableX video room and start the session |
func callReject() |
User taps Decline | Notify the remote caller, release resources |
func callTimeOut() |
No response within 45 seconds | Dismiss UI, notify caller of missed call |
func callEnd() |
Active call ends (local or remote) | Clean up the video session and return to the idle state |
func callHold() |
User places the call on hold | Pause media streams, show on-hold state in your UI |
extension CallNotificationHandler: EnxCallKitDelegate {
func callAnswer() {
// Start the EnableX video session
VideoSessionManager.shared.connect(roomId: roomId, token: token)
}
func callReject() {
// Notify the remote caller and clean up
signallingServer.sendReject(to: callerId)
}
func callTimeOut() {
// 45 seconds elapsed with no response — call auto-dismissed
signallingServer.sendMissedCall(to: callerId)
}
func callEnd() {
// Session ended — return to idle
VideoSessionManager.shared.disconnect()
}
func callHold() {
// Put media on hold
VideoSessionManager.shared.hold()
}
}
- iOS UI Kit — Full audio/video room UI built on top of the EnableX iOS SDK. Pair with the Calling UI SDK for a complete calling experience.
- iOS Video SDK — The underlying SDK for building custom video UIs.
- Apple CallKit documentation — The system framework that the iOS Calling UI SDK is built upon.