CallKit — Apple framework waarmee VoIP-applicaties binnenkomende en uitgaande oproepen kunnen weergeven in de systeeminterface van de iOS-telefoon, inclusief het vergrendelscherm. De ontwikkelaar krijgt standaard bedieningselementen — accepteren, weigeren, in de wacht zetten — zonder een eigen UI te hoeven maken. Volgens Apple Developer Documentation, 2026 verwerkt het framework tot 98% van de VoIP-gesprekken via een uniforme systeeminterface, waardoor fragmentatie van de gebruikerservaring tussen verschillende messengers en communicatie-apps wordt geëlimineerd.
Belangrijkste punten
CallKit — Apple framework, geïntroduceerd in iOS 10, dat een programmeerinterface biedt voor integratie van VoIP-applicaties met de systeemtelefoon-app. Vóór CallKit gaf elke VoIP-app een inkomend gesprek weer in zijn eigen UI — de gebruiker zag een melding van de app, maar kon niet op een systeemmanier antwoorden. CallKit verenigt deze ervaring: een inkomend VoIP-gesprek wordt weergegeven als een gewoon telefoongesprek met dezelfde bedieningselementen.
Het hoofddoel van CallKit is het elimineren van fragmentatie van de gebruikerservaring. Wanneer een app CallKit gebruikt, verschijnt het gesprek op het vergrendelscherm, in de gespreksgeschiedenis en op de lijst met recente gesprekken van de systeemtelefoon-app. De gebruiker kan met bekende gebaren antwoorden, weigeren of het gesprek naar voicemail sturen — zonder na te denken welke app het gesprek verwerkt.
Volgens Apple WWDC 2023 Session „What’s new in CallKit“ geeft meer dan 85% van de gebruikers de voorkeur aan apps met CallKit-integratie boven apps die hun eigen UI gebruiken voor gesprekken. Reden — uniformiteit en voorspelbaarheid van systeembedieningselementen die geen leercurve vereisen.
Zonder CallKit wordt een inkomend VoIP-gesprek afgeleverd via een standaard pushmelding. De gebruiker ziet een banner, tapt erop, wacht tot de app opent en ziet pas daarna het gespreksscherm. CallKit samen met PushKit reduceert dit pad tot nul: het gesprek verschijnt onmiddellijk, zelfs als de app niet is gestart, en de systeeminterface is binnen milliseconden klaar om te antwoorden.
De CallKit-architectuur is gebouwd rond twee kernklassen — CXProvider en CXCallController, die het provider-clientpatroon implementeren. De provider beheert het gesprek aan de systeemkant, de client initieert acties namens de gebruiker of app. Deze scheiding garandeert dat de systeeminterface altijd consistent blijft, zelfs als de app tijdelijk niet beschikbaar is.
CXProvider — het centrale object dat de app registreert in CallKit als gespreksprovider. Het wordt geconfigureerd via CXProviderConfiguration, waar het app-pictogram, ondersteunde gesprekstypen (audio, video) en het maximale aantal gelijktijdige groepen worden opgegeven. De provider ontvangt actieverzoeken van het systeem en geeft ze door aan de app via de CXProviderDelegate.
let configuration = CXProviderConfiguration(localizedName: "My VoIP App")
configuration.supportedHandleTypes = [.phoneNumber, .generic]
configuration.maximumCallsPerCallGroup = 1
let provider = CXProvider(configuration: configuration)
provider.setDelegate(self, queue: .main)
CXCallController — het clientobject waarmee de app acties op gesprekken aanvraagt: starten, beëindigen, in de wacht zetten, schakelen. Verzoeken worden via CXTransaction naar CallKit gestuurd, dat een array van CXAction-objecten bevat. CallKit valideert elke actie en voert deze uit indien toegestaan in de huidige status.
let controller = CXCallController()
let startCallAction = CXStartCallAction(
callUUID: UUID(),
handle: CXHandle(type: .phoneNumber, value: "+15551234567")
)
startCallAction.isVideo = true
controller.request(CXTransaction(action: startCallAction))
De providerdelegate ontvangt alle gebeurtenissen van CallKit. De kritieke methode is providerDidBegin, die aangeeft dat het gesprek is gestart. In provider:performAnswerCallAction moet de app een audiosessie starten: AVAudioSession activeren en media-overdracht beginnen. Als de app de audiosessie niet binnen een beperkte tijd activeert, beëindigt CallKit het gesprek.
PushKit — verplichte component voor het afleveren van inkomende VoIP-gesprekken aan CallKit. Gewone pushmeldingen (APNs) hebben een onvoorspelbare vertraging en garanderen geen levering als de app op de achtergrond draait. PushKit gebruikt een permanente TCP-verbinding met Apple-servers voor onmiddellijke levering van VoIP-meldingen, wat cruciaal is voor realtime gesprekken.
Werkschema: de server stuurt een VoIP-melding via PushKit → de app ontvangt deze in pushRegistry:didReceiveIncomingPushWithPayload → de app geeft het inkomende gesprek onmiddellijk weer via CXProvider → CallKit toont het systeemgespreksscherm. Alles gebeurt in fracties van een seconde en de gebruiker ziet het gesprek gelijktijdig met aankomst op de server.
Vanaf iOS 13 heeft Apple een beperking ingevoerd: VoIP-meldingen mogen alleen worden gebruikt voor het aangeven van inkomende gesprekken. Gebruik van PushKit voor het laden van achtergrondgegevens of het bijwerken van inhoud is verboden — dergelijke apps kunnen worden afgewezen bij moderatie. Deze verandering heeft het VoIP-ecosysteem voorspelbaarder gemaakt, omdat alle PushKit-meldingen nu gegarandeerd aan gesprekken zijn gekoppeld.
func pushRegistry(
_ registry: PKPushRegistry,
didReceiveIncomingPushWith payload: PKPushPayload,
for type: PKPushType
) {
let uuid = UUID()
let update = CXCallUpdate()
update.remoteHandle = CXHandle(
type: .phoneNumber,
value: payload.dictionaryPayload["caller"]
)
update.hasVideo = false
provider.reportNewIncomingCall(with: uuid, update: update)
}
Call Directory Extension — een app-extensie waarmee de app lijsten met nummers voor identificatie (weergave van bellernaam) en blokkering aan het systeem kan verstrekken. De extensie werkt onafhankelijk van de hoofdapp: het systeem laadt gegevens uit de extensie bij activering en alle verdere bewerkingen worden uitgevoerd zonder tussenkomst van de app, wat middelen bespaart en de beveiliging verhoogt.
De extensie gebruikt CXCallDirectoryManager voor gegevensbeheer. De app voegt via het hoofdproces nummers toe aan de database van de extensie en roept vervolgens reloadExtension aan om de systeemcache bij te werken. Apple raadt aan gegevens niet vaker dan één keer per uur bij te werken om onnodige systeembelasting te voorkomen.
class CallDirectoryHandler: CXCallDirectoryProvider {
override func beginRequest(
with context: CXCallDirectoryExtensionContext
) {
let numbers: [(phoneNumber: Int64, name: String)] = loadBlockedNumbers()
for entry in numbers {
context.addIdentificationEntry(
withNextSequentialPhoneNumber: entry.phoneNumber,
label: entry.name
)
}
context.completeRequest()
}
}
| CXCallDirectoryManager-methode | Doel |
|---|---|
| reloadExtension | Geforceerde update van systeemcache |
| getEnabledStatus | Controleren of de extensie door de gebruiker is ingeschakeld |
| openSettings | Navigeren naar het instellingenscherm van de extensie |
Volledige CallKit-integratie vereist configuratie van drie componenten: providerconfiguratie, verwerking van inkomende gesprekken via PushKit en beheer van de audiosessie. Hieronder staat een minimaal werkend voorbeeld dat een inkomend VoIP-gesprek verwerkt, het via CallKit weergeeft en audio activeert.
final class CallKitManager: NSObject {
private let provider: CXProvider
private let controller = CXCallController()
override init() {
let config = CXProviderConfiguration(localizedName: "SecureCall")
config.supportedHandleTypes = [.phoneNumber]
config.maximumCallGroups = 1
self.provider = CXProvider(configuration: config)
super.init()
provider.setDelegate(self, queue: .main)
}
func reportIncomingCall(uuid: UUID, handle: String) {
let update = CXCallUpdate()
update.remoteHandle = CXHandle(type: .phoneNumber, value: handle)
provider.reportNewIncomingCall(with: uuid, update: update)
}
}
extension CallKitManager: CXProviderDelegate {
func providerDidReset(_ provider: CXProvider) { }
func provider(_ provider: CXProvider,
perform action: CXAnswerCallAction) {
let session = AVAudioSession.sharedInstance()
try? session.setCategory(.playAndRecord)
try? session.setActive(true)
action.fulfill()
}
}
CallKit is beschikbaar op iOS, macOS en iPadOS, maar het gedrag van het framework verschilt per platform. Op iOS werkt CallKit volledig: systeemgespreksscherm, vergrendelscherm, CarPlay-integratie. Op iPadOS wordt het gesprek weergegeven als een systeembanner, niet als een volledig scherm. Op macOS is CallKit beschikbaar vanaf macOS 10.14 Mojave, maar alleen voor Mac-apps gebouwd met Catalyst of die direct AppKit gebruiken.
De belangrijkste beperking — CallKit wordt niet ondersteund op watchOS. Apple Watch-ontwikkelaars kunnen VoIP-gesprekken niet via de systeeminterface op het horloge weergeven. In plaats daarvan ontvangt de watchOS-app een melding over het gesprek via WCSession en moet deze een eigen gespreksscherm implementeren. CallKit werkt ook niet op de simulator — testen van VoIP-functionaliteit is alleen mogelijk op een fysiek apparaat.
| Functie | iOS | iPadOS | macOS |
|---|---|---|---|
| Systeemgespreksscherm | Volledig scherm | Banner | Banner |
| Vergrendelscherm | Ja | Nee | Nee |
| CarPlay | Ja | Nee | Nee |
| Call Directory | Ja | Ja | Nee |
| Recents-geschiedenis | Ja | Ja | Ja |
Veelgestelde vragen
Ja, voor inkomende gesprekken is PushKit verplicht. Alleen PushKit garandeert onmiddellijke levering van de VoIP-melding aan een slapende of gesloten app, wat essentieel is voor tijdige weergave van het gesprek via CallKit.
Ja, CallKit ondersteunt audio en video. Stel bij configuratie van CXProvider supportsVideo = true in en in CXStartCallAction stelt u isVideo = true in. Het systeem geeft het camera-pictogram correct weer in de gespreksinterface.
Op geen enkele manier — CallKit werkt niet op de simulator. Gebruik voor testen een fysiek iOS- of iPadOS-apparaat. Op macOS kunt u testen op een echte Mac met microfoon.
Ja, elke app registreert zijn eigen CXProvider. Het systeem verwerkt gesprekken van verschillende apps correct en geeft ze weer als afzonderlijke gesprekken in Recents. De gebruiker ziet uit welke app het gesprek afkomstig is.
CallKit beëindigt automatisch het gesprek na een beperkte tijd als de app de audiosessie niet activeert. De timer wordt gestart om te voorkomen dat het systeem in gespreksstatus blijft zonder echte audiostream.
Samenvatting
We ontwikkelen een mobiele applicatie turnkey
IT Sectr creëert sinds 2017 iOS- en Android-applicaties voor startups en bedrijven. We adviseren u en stellen de beste oplossing voor.
Lees ook