CallKit — framework Apple, který umožňuje VoIP aplikacím zobrazovat příchozí a odchozí hovory v systémovém rozhraní telefonu iOS, včetně uzamčené obrazovky. Vývojář získává standardní ovládací prvky — přijetí, odmítnutí, podržení hovoru — bez nutnosti vytvářet vlastní UI. Podle Apple Developer Documentation, 2026 framework zpracovává až 98% VoIP hovorů prostřednictvím jednotného systémového rozhraní, čímž eliminuje fragmentaci uživatelského zážitku mezi různými messengery a komunikačními aplikacemi.
Hlavní body
CallKit — framework Apple, představený v iOS 10, který poskytuje programové rozhraní pro integraci VoIP aplikací se systémovou telefonní aplikací. Před příchodem CallKit každá VoIP aplikace zobrazovala příchozí hovor ve vlastním UI — uživatel viděl oznámení od aplikace, ale nemohl odpovědět systémovým způsobem. CallKit sjednocuje tento zážitek: příchozí VoIP hovor se zobrazí jako běžný telefonní hovor se stejnými ovládacími prvky.
Hlavním cílem CallKit je odstranění fragmentace uživatelského zážitku. Když aplikace používá CallKit, hovor se objeví na uzamčené obrazovce, v historii hovorů a v seznamu nedávných hovorů systémové aplikace Telefon. Uživatel může odpovědět, odmítnout nebo odeslat hovor do hlasové schránky známými gesty — aniž by přemýšlel, která aplikace hovor zpracovává.
Podle Apple WWDC 2023 Session „What’s new in CallKit“ dává více než 85% uživatelů přednost aplikacím s integrací CallKit před těmi, které používají vlastní UI pro hovory. Důvodem je jednotnost a předvídatelnost systémových ovládacích prvků, které nevyžadují učení.
Bez CallKit je příchozí VoIP hovor doručen prostřednictvím standardního push oznámení. Uživatel vidí banner, klepne na něj, čeká na otevření aplikace a teprve poté vidí obrazovku hovoru. CallKit spolu s PushKit zkracuje tuto cestu na nulu: hovor se zobrazí okamžitě, i když aplikace není spuštěna, a systémové rozhraní je připraveno odpovědět v milisekundách.
Architektura CallKit je postavena kolem dvou klíčových tříd — CXProvider a CXCallController, které implementují vzor provider-client. Provider spravuje hovor na straně systému, client iniciuje akce jménem uživatele nebo aplikace. Toto oddělení zaručuje, že systémové rozhraní zůstává vždy konzistentní, i když je aplikace dočasně nedostupná.
CXProvider — centrální objekt, který registruje aplikaci v CallKit jako poskytovatele hovorů. Konfiguruje se prostřednictvím CXProviderConfiguration, kde se zadává ikona aplikace, podporované typy hovorů (audio, video) a maximální počet současných skupin. Provider přijímá od systému požadavky na akce a předává je aplikaci prostřednictvím delegáta 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 — klientský objekt, prostřednictvím kterého aplikace požaduje akce nad hovory: zahájení, ukončení, podržení, přepnutí. Požadavky jsou odesílány do CallKit prostřednictvím CXTransaction, který obsahuje pole objektů CXAction. CallKit každou akci validuje a provede ji, pokud je v aktuálním stavu povolena.
let controller = CXCallController()
let startCallAction = CXStartCallAction(
callUUID: UUID(),
handle: CXHandle(type: .phoneNumber, value: "+15551234567")
)
startCallAction.isVideo = true
controller.request(CXTransaction(action: startCallAction))
Delegát provideru přijímá všechny události od CallKit. Kritickou metodou je providerDidBegin, signalizující zahájení hovoru. V provider:performAnswerCallAction musí aplikace spustit audio relaci: aktivovat AVAudioSession a zahájit přenos médií. Pokud aplikace neaktivuje audio relaci v omezeném čase, CallKit hovor ukončí.
PushKit — povinná komponenta pro doručování příchozích VoIP hovorů do CallKit. Běžná push oznámení (APNs) mají nepředvídatelné zpoždění a nezaručují doručení, pokud je aplikace na pozadí. PushKit používá trvalé TCP připojení k serverům Apple pro okamžité doručení VoIP oznámení, což je kritické pro hovory v reálném čase.
Schéma fungování: server odešle VoIP oznámení přes PushKit → aplikace jej přijme v pushRegistry:didReceiveIncomingPushWithPayload → aplikace okamžitě zobrazí příchozí hovor přes CXProvider → CallKit zobrazí systémovou obrazovku hovoru. Vše se děje ve zlomku sekundy a uživatel vidí hovor současně s jeho příchodem na server.
Od iOS 13 Apple zavedl omezení: VoIP oznámení by měla být používána pouze pro indikaci příchozích hovorů. Použití PushKit pro načítání dat na pozadí nebo aktualizaci obsahu je zakázáno — takové aplikace mohou být při moderování odmítnuty. Tato změna učinila VoIP ekosystém předvídatelnějším, protože všechna PushKit oznámení jsou nyní garantovaně spojena s hovory.
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 — rozšíření aplikace, které umožňuje aplikaci poskytovat systému seznamy čísel pro identifikaci (zobrazení jména volajícího) a blokování. Rozšíření pracuje nezávisle na hlavní aplikaci: systém načítá data z rozšíření při aktivaci a všechny další operace jsou prováděny bez účasti aplikace, což šetří prostředky a zvyšuje bezpečnost.
Rozšíření používá CXCallDirectoryManager pro správu dat. Aplikace prostřednictvím hlavního procesu přidává čísla do databáze rozšíření a poté volá reloadExtension pro aktualizaci systémové mezipaměti. Apple doporučuje aktualizovat data ne častěji než jednou za hodinu, aby se předešlo zbytečnému zatížení systému.
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()
}
}
| Metoda CXCallDirectoryManager | Účel |
|---|---|
| reloadExtension | Vynucená aktualizace systémové mezipaměti |
| getEnabledStatus | Kontrola, zda je rozšíření povoleno uživatelem |
| openSettings | Přechod na obrazovku nastavení rozšíření |
Plná integrace CallKit vyžaduje konfiguraci tří komponent: konfiguraci provideru, zpracování příchozích hovorů přes PushKit a správu audio relace. Níže je minimální funkční příklad, který zpracovává příchozí VoIP hovor, zobrazuje jej přes CallKit a aktivuje audio.
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 je dostupný na iOS, macOS a iPadOS, ale chování frameworku se mezi platformami liší. Na iOS CallKit funguje v plném rozsahu: systémová obrazovka hovoru, uzamčená obrazovka, integrace s CarPlay. Na iPadOS se hovor zobrazuje jako systémový banner, nikoli jako rozhraní přes celou obrazovku. Na macOS je CallKit dostupný od macOS 10.14 Mojave, ale pouze pro Mac aplikace postavené s Catalyst nebo přímo používající AppKit.
Klíčové omezení — CallKit není podporován na watchOS. Vývojáři Apple Watch nemohou zobrazovat VoIP hovory prostřednictvím systémového rozhraní na hodinkách. Místo toho aplikace watchOS obdrží oznámení o hovoru přes WCSession a musí implementovat vlastní obrazovku hovoru. CallKit také nefunguje na simulátoru — testování VoIP funkcí je možné pouze na fyzickém zařízení.
| Funkce | iOS | iPadOS | macOS |
|---|---|---|---|
| Systémová obrazovka hovoru | Celá obrazovka | Banner | Banner |
| Uzamčená obrazovka | Ano | Ne | Ne |
| CarPlay | Ano | Ne | Ne |
| Call Directory | Ano | Ano | Ne |
| Historie Recents | Ano | Ano | Ano |
Často kladené otázky
Ano, pro příchozí hovory je PushKit povinný. Pouze PushKit garantuje okamžité doručení VoIP oznámení uspané nebo uzavřené aplikaci, což je kritické pro včasné zobrazení hovoru prostřednictvím CallKit.
Ano, CallKit podporuje audio a video. Při konfiguraci CXProvider nastavte supportsVideo = true a v CXStartCallAction nastavte isVideo = true. Systém správně zobrazí ikonu kamery v rozhraní hovoru.
Nijak — CallKit nefunguje na simulátoru. Pro testování použijte fyzické zařízení iOS nebo iPadOS. Na macOS můžete testovat na reálném Macu s mikrofonem.
Ano, každá aplikace registruje svůj vlastní CXProvider. Systém správně zpracovává hovory z různých aplikací a zobrazuje je jako samostatné hovory v Recents. Uživatel vidí, ze které aplikace hovor přišel.
CallKit automaticky ukončí hovor po omezeném čase, pokud aplikace neaktivuje audio relaci. Časovač se spouští, aby systém nezůstal ve stavu hovoru bez reálného audio proudu.
Shrnutí
Vyvineme mobilní aplikaci na klíč
IT Sectr vytváří aplikace pro iOS a Android pro startupy a podniky od roku 2017. Poradíme vám a navrhneme nejlepší řešení.
Přečtěte si také