CallKit — Apple-ramverk som gör att VoIP-applikationer kan visa inkommande och utgående samtal i systemgränssnittet för iOS-telefonen, inklusive låsskärmen. Utvecklaren får standardkontroller — acceptera, avvisa, håll samtal — utan att behöva skapa ett eget UI. Enligt Apple Developer Documentation, 2026 bearbetar ramverket upp till 98% av VoIP-samtalen via ett enhetligt systemgränssnitt, vilket eliminerar fragmentering av användarupplevelsen mellan olika meddelande- och kommunikationsapplikationer.
Huvudpunkter
CallKit — Apple-ramverk, introducerat i iOS 10, som tillhandahåller ett programmeringsgränssnitt för integration av VoIP-applikationer med systemets telefonapp. Före CallKit visade varje VoIP-app ett inkommande samtal i sitt eget UI — användaren såg en avisering från appen men kunde inte svara på systemets sätt. CallKit förenar denna upplevelse: inkommande VoIP-samtal visas som ett vanligt telefonsamtal med samma kontroller.
Huvudmålet med CallKit är att eliminera fragmentering av användarupplevelsen. När en app använder CallKit visas samtalet på låsskärmen, i samtalshistoriken och i listan över senaste samtal i systemets Telefon-app. Användaren kan svara, avvisa eller skicka samtalet till röstbrevlådan med bekanta gester — utan att tänka på vilken app som bearbetar samtalet.
Enligt Apple WWDC 2023 Session “What’s new in CallKit” föredrar över 85% av användarna appar med CallKit-integration framför de som använder eget UI för samtal. Anledningen är enhetligheten och förutsägbarheten hos systemkontroller som inte kräver inlärning.
Utan CallKit levereras inkommande VoIP-samtal via en standard push-avisering. Användaren ser en banner, trycker på den, väntar på att appen öppnas och först därefter ser samtalskärmen. CallKit tillsammans med PushKit reducerar denna väg till noll: samtalet visas omedelbart, även om appen inte är startad, och systemgränssnittet är redo att svara inom millisekunder.
CallKit-arkitekturen är uppbyggd kring två nyckelklasser — CXProvider och CXCallController, som implementerar leverantörs-klientmönstret. Leverantören hanterar samtalet från systemets sida, klienten initierar åtgärder på uppdrag av användaren eller appen. Denna uppdelning garanterar att systemgränssnittet alltid förblir konsekvent, även om appen är tillfälligt otillgänglig.
CXProvider — det centrala objektet som registrerar appen i CallKit som samtalsleverantör. Det konfigureras via CXProviderConfiguration, där appikonen, typer av samtal som stöds (ljud, video) och maximalt antal samtidiga grupper anges. Leverantören tar emot åtgärdsbegäranden från systemet och vidarebefordrar dem till appen via delegaten 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 — klientobjektet genom vilket appen begär åtgärder på samtal: start, avslut, håll, växling. Begäranden skickas till CallKit via CXTransaction, som innehåller en array av CXAction-objekt. CallKit validerar varje åtgärd och utför den om den är tillåten i det aktuella tillståndet.
let controller = CXCallController()
let startCallAction = CXStartCallAction(
callUUID: UUID(),
handle: CXHandle(type: .phoneNumber, value: "+15551234567")
)
startCallAction.isVideo = true
controller.request(CXTransaction(action: startCallAction))
Leverantörens delegat tar emot alla händelser från CallKit. Den kritiska metoden är providerDidBegin, som signalerar att samtalet har startat. I provider:performAnswerCallAction måste appen starta en ljudsession: aktivera AVAudioSession och påbörja mediaöverföring. Om appen inte aktiverar ljudsessionen inom en begränsad tid kommer CallKit att avsluta samtalet.
PushKit — obligatorisk komponent för leverans av inkommande VoIP-samtal till CallKit. Vanliga push-aviseringar (APNs) har oförutsägbar fördröjning och garanterar inte leverans om appen är i bakgrunden. PushKit använder en permanent TCP-anslutning till Apples servrar för omedelbar leverans av VoIP-aviseringar, vilket är avgörande för realtidssamtal.
Arbetsschema: servern skickar en VoIP-avisering via PushKit → appen tar emot den i pushRegistry:didReceiveIncomingPushWithPayload → appen visar omedelbart det inkommande samtalet via CXProvider → CallKit visar systemets samtalskärm. Allt sker på bråkdelen av en sekund och användaren ser samtalet samtidigt som det anländer till servern.
Från och med iOS 13 införde Apple en begränsning: VoIP-aviseringar ska användas endast för indikation av inkommande samtal. Användning av PushKit för bakgrundsladdning av data eller uppdatering av innehåll är förbjuden — sådana appar kan avvisas vid moderering. Denna förändring gjorde VoIP-ekosystemet mer förutsägbart, eftersom alla PushKit-aviseringar nu garanterat är kopplade till samtal.
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 — ett apptillägg som gör att appen kan förse systemet med listor över nummer för identifiering (visning av uppringarens namn) och blockering. Tillägget fungerar oberoende av huvudappen: systemet laddar data från tillägget vid aktivering, och alla efterföljande operationer utförs utan appens medverkan, vilket sparar resurser och ökar säkerheten.
Tillägget använder CXCallDirectoryManager för datahantering. Appen lägger via huvudprocessen till nummer i tilläggets databas och anropar sedan reloadExtension för att uppdatera systemets cache. Apple rekommenderar att data uppdateras högst en gång i timmen för att undvika onödig systembelastning.
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-metod | Syfte |
|---|---|
| reloadExtension | Tvingad uppdatering av systemets cache |
| getEnabledStatus | Kontrollera om tillägget är aktiverat av användaren |
| openSettings | Navigera till tilläggets inställningsskärm |
Fullständig CallKit-integration kräver konfigurering av tre komponenter: leverantörskonfiguration, bearbetning av inkommande samtal via PushKit och hantering av ljudsessionen. Nedan är ett minimalt fungerande exempel som bearbetar ett inkommande VoIP-samtal, visar det via CallKit och aktiverar ljud.
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 är tillgängligt på iOS, macOS och iPadOS, men ramverkets beteende skiljer sig mellan plattformar. På iOS fungerar CallKit fullt ut: systemets samtalskärm, låsskärm, CarPlay-integration. På iPadOS visas samtalet som en systembanner, inte som ett helskärmsgränssnitt. På macOS är CallKit tillgängligt från macOS 10.14 Mojave, men endast för Mac-appar byggda med Catalyst eller som direkt använder AppKit.
Den viktigaste begränsningen — CallKit stöds inte på watchOS. Apple Watch-utvecklare kan inte visa VoIP-samtal via systemgränssnittet på klockan. Istället får watchOS-appen en avisering om samtalet via WCSession och måste implementera en egen samtalskärm. CallKit fungerar inte heller på simulatorn — testning av VoIP-funktioner är endast möjlig på en fysisk enhet.
| Funktion | iOS | iPadOS | macOS |
|---|---|---|---|
| Systemets samtalskärm | Helskärm | Banner | Banner |
| Låsskärm | Ja | Nej | Nej |
| CarPlay | Ja | Nej | Nej |
| Call Directory | Ja | Ja | Nej |
| Recents-historik | Ja | Ja | Ja |
Vanliga frågor
Ja, för inkommande samtal är PushKit obligatoriskt. Endast PushKit garanterar omedelbar leverans av VoIP-aviseringen till en sovande eller stängd app, vilket är avgörande för att samtalet ska visas i tid via CallKit.
Ja, CallKit stöder ljud och video. Vid konfigurering av CXProvider ställ in supportsVideo = true och i CXStartCallAction ställ in isVideo = true. Systemet visar korrekt kameraikonen i samtalsgränssnittet.
Inte alls — CallKit fungerar inte på simulatorn. För testning använd en fysisk iOS- eller iPadOS-enhet. På macOS kan du testa på en riktig Mac med mikrofon.
Ja, varje app registrerar sin egen CXProvider. Systemet bearbetar samtal från olika appar korrekt och visar dem som separata samtal i Recents. Användaren ser vilken app samtalet kom från.
CallKit avslutar automatiskt samtalet efter en begränsad tid om appen inte aktiverar ljudsessionen. Timern startas för att systemet inte ska stanna kvar i samtalsstatus utan verklig ljudström.
Sammanfattning
Vi utvecklar en mobil applikation nyckelfärdigt
IT Sectr skapar iOS- och Android-applikationer för startups och företag sedan 2017. Vi ger dig råd och föreslår den bästa lösningen.
Läs också