CallKit — framework Apple care permite aplicațiilor VoIP să afișeze apelurile primite și efectuate în interfața de sistem a telefonului iOS, inclusiv pe ecranul de blocare. Dezvoltatorul primește elemente de control standard — acceptare, respingere, punere în așteptare — fără a fi nevoie să creeze propriul UI. Potrivit Apple Developer Documentation, 2026, framework-ul procesează până la 98% din apelurile VoIP printr-o interfață de sistem unică, eliminând fragmentarea experienței utilizatorului între diferite mesagerii și aplicații de comunicare.
Principalele puncte
CallKit — framework Apple, introdus în iOS 10, care oferă o interfață de programare pentru integrarea aplicațiilor VoIP cu aplicația telefonică de sistem. Înainte de apariția CallKit, fiecare aplicație VoIP afișa apelul primit în propriul UI — utilizatorul vedea o notificare de la aplicație, dar nu putea răspunde în modul de sistem. CallKit unifică această experiență: apelul VoIP primit este afișat ca un apel telefonic obișnuit cu aceleași elemente de control.
Scopul principal al CallKit este eliminarea fragmentării experienței utilizatorului. Când aplicația folosește CallKit, apelul apare pe ecranul de blocare, în istoricul apelurilor și în lista apelurilor recente ale aplicației de sistem Telefon. Utilizatorul poate răspunde, respinge sau trimite apelul la căsuța vocală cu gesturi familiare — fără să se gândească ce aplicație procesează apelul.
Potrivit Apple WWDC 2023 Session „What’s new in CallKit“, peste 85% dintre utilizatori preferă aplicațiile cu integrare CallKit față de cele care folosesc propriul UI pentru apeluri. Motivul — uniformitatea și predictibilitatea elementelor de control de sistem care nu necesită învățare.
Fără CallKit, apelul VoIP primit este livrat printr-o notificare push standard. Utilizatorul vede un banner, atinge pe el, așteaptă deschiderea aplicației și abia apoi vede ecranul de apel. CallKit împreună cu PushKit reduce acest drum la zero: apelul apare instantaneu, chiar dacă aplicația nu este pornită, iar interfața de sistem este gata de răspuns în milisecunde.
Arhitectura CallKit este construită în jurul a două clase cheie — CXProvider și CXCallController, care implementează modelul provider-client. Providerul gestionează apelul din partea sistemului, clientul inițiază acțiuni din partea utilizatorului sau a aplicației. Această separare garantează că interfața de sistem rămâne întotdeauna consecventă, chiar dacă aplicația este temporar indisponibilă.
CXProvider — obiectul central care înregistrează aplicația în CallKit ca furnizor de apeluri. Se configurează prin CXProviderConfiguration, unde se specifică iconița aplicației, tipurile de apeluri suportate (audio, video) și numărul maxim de grupuri simultane. Providerul primește de la sistem solicitări de acțiuni și le transmite aplicației prin delegatul 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 — obiectul client prin care aplicația solicită acțiuni asupra apelurilor: începere, încheiere, punere în așteptare, comutare. Solicitările sunt transmise către CallKit prin CXTransaction, care conține un tablou de obiecte CXAction. CallKit validează fiecare acțiune și o execută dacă este permisă în starea curentă.
let controller = CXCallController()
let startCallAction = CXStartCallAction(
callUUID: UUID(),
handle: CXHandle(type: .phoneNumber, value: "+15551234567")
)
startCallAction.isVideo = true
controller.request(CXTransaction(action: startCallAction))
Delegatul providerului primește toate evenimentele de la CallKit. Metoda critică — providerDidBegin, semnalând că apelul a început. În provider:performAnswerCallAction aplicația trebuie să înceapă o sesiune audio: să activeze AVAudioSession și să înceapă transmiterea media. Dacă aplicația nu activează sesiunea audio într-un timp limitat, CallKit va încheia apelul.
PushKit — componenta obligatorie pentru livrarea apelurilor VoIP primite către CallKit. Notificările push obișnuite (APNs) au o întârziere imprevizibilă și nu garantează livrarea dacă aplicația este în fundal. PushKit folosește o conexiune TCP permanentă cu serverele Apple pentru livrarea instantanee a notificărilor VoIP, ceea ce este esențial pentru apelurile în timp real.
Schema de funcționare: serverul trimite o notificare VoIP prin PushKit → aplicația o primește în pushRegistry:didReceiveIncomingPushWithPayload → aplicația afișează imediat apelul primit prin CXProvider → CallKit arată ecranul de sistem al apelului. Totul se întâmplă în fracțiuni de secundă, iar utilizatorul vede apelul simultan cu sosirea sa pe server.
Începând cu iOS 13, Apple a introdus o restricție: notificările VoIP trebuie utilizate doar pentru indicarea apelurilor primite. Utilizarea PushKit pentru încărcarea datelor în fundal sau actualizarea conținutului este interzisă — astfel de aplicații pot fi respinse la moderare. Această schimbare a făcut ecosistemul VoIP mai previzibil, deoarece toate notificările PushKit sunt acum garantat legate de apeluri.
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 — extensie de aplicație care permite aplicației să furnizeze sistemului liste de numere pentru identificare (afișarea numelui apelantului) și blocare. Extensia funcționează independent de aplicația principală: sistemul încarcă datele din extensie la activare, iar toate operațiile ulterioare se execută fără participarea aplicației, economisind resurse și sporind securitatea.
Extensia folosește CXCallDirectoryManager pentru gestionarea datelor. Aplicația, prin procesul principal, adaugă numere în baza de date a extensiei, apoi apelează reloadExtension pentru actualizarea cache-ului de sistem. Apple recomandă actualizarea datelor nu mai des de o dată pe oră pentru a evita încărcarea inutilă a sistemului.
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 | Destinație |
|---|---|
| reloadExtension | Actualizarea forțată a cache-ului de sistem |
| getEnabledStatus | Verificarea dacă extensia este activată de utilizator |
| openSettings | Navigarea la ecranul de setări al extensiei |
Integrarea completă CallKit necesită configurarea a trei componente: configurarea providerului, procesarea apelurilor primite prin PushKit și gestionarea sesiunii audio. Mai jos este un exemplu minim funcțional care procesează un apel VoIP primit, îl afișează prin CallKit și activează 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 este disponibil pe iOS, macOS și iPadOS, dar comportamentul framework-ului diferă între platforme. Pe iOS CallKit funcționează în totalitate: ecran de sistem al apelului, ecran de blocare, integrare cu CarPlay. Pe iPadOS afișarea apelului are loc sub formă de banner de sistem, nu de interfață pe ecran complet. Pe macOS CallKit este disponibil de la macOS 10.14 Mojave, dar numai pentru aplicațiile Mac construite cu Catalyst sau care folosesc AppKit direct.
Limitarea cheie — CallKit nu este suportat pe watchOS. Dezvoltatorii Apple Watch nu pot afișa apeluri VoIP prin interfața de sistem pe ceas. În schimb, aplicația watchOS primește o notificare despre apel prin WCSession și trebuie să implementeze propriul ecran de apel. De asemenea, CallKit nu funcționează pe simulator — testarea funcțiilor VoIP este posibilă doar pe un dispozitiv fizic.
| Funcție | iOS | iPadOS | macOS |
|---|---|---|---|
| Ecran de sistem al apelului | Ecran complet | Banner | Banner |
| Ecran de blocare | Da | Nu | Nu |
| CarPlay | Da | Nu | Nu |
| Call Directory | Da | Da | Nu |
| Istoric Recents | Da | Da | Da |
Întrebări frecvente
Da, pentru apelurile primite PushKit este obligatoriu. Doar PushKit garantează livrarea instantanee a notificării VoIP către aplicația adormită sau închisă, ceea ce este esențial pentru afișarea la timp a apelului prin CallKit.
Da, CallKit suportă audio și video. La configurarea CXProvider setați supportsVideo = true, iar în CXStartCallAction setați isVideo = true. Sistemul va afișa corect pictograma camerei în interfața apelului.
În niciun fel — CallKit nu funcționează pe simulator. Pentru testare utilizați un dispozitiv fizic iOS sau iPadOS. Pe macOS puteți testa pe un Mac real cu microfon.
Da, fiecare aplicație își înregistrează propriul CXProvider. Sistemul procesează corect apelurile de la diferite aplicații și le afișează ca apeluri separate în Recents. Utilizatorul vede din ce aplicație a venit apelul.
CallKit va încheia automat apelul după un timp limitat dacă aplicația nu activează sesiunea audio. Timerul pornește pentru ca sistemul să nu rămână în stare de apel fără un flux audio real.
Rezumat
Vom dezvolta o aplicație mobilă la cheie
IT Sectr creează aplicații iOS și Android pentru startup-uri și afaceri din 2017. Vă vom consilia și vă vom propune cea mai bună soluție.
Citiți și