CallKit — framework Apple yang memungkinkan aplikasi VoIP menampilkan panggilan masuk dan keluar di antarmuka sistem telepon iOS, termasuk layar kunci. Pengembang mendapatkan kontrol standar — menerima, menolak, menahan panggilan — tanpa perlu membuat UI sendiri. Menurut Apple Developer Documentation, 2026, framework ini memproses hingga 98% panggilan VoIP melalui antarmuka sistem terpadu, yang menghilangkan fragmentasi pengalaman pengguna di berbagai aplikasi perpesanan dan komunikasi.
Poin utama
CallKit — framework Apple, diperkenalkan di iOS 10, yang menyediakan antarmuka pemrograman untuk integrasi aplikasi VoIP dengan aplikasi telepon sistem. Sebelum CallKit, setiap aplikasi VoIP menampilkan panggilan masuk di UI sendiri — pengguna melihat notifikasi dari aplikasi tetapi tidak dapat menjawab dengan cara sistem. CallKit menyatukan pengalaman ini: panggilan VoIP masuk ditampilkan seperti panggilan telepon biasa dengan kontrol yang sama.
Tujuan utama CallKit adalah menghilangkan fragmentasi pengalaman pengguna. Saat aplikasi menggunakan CallKit, panggilan muncul di layar kunci, riwayat panggilan, dan daftar panggilan terbaru aplikasi Telepon sistem. Pengguna dapat menjawab, menolak, atau mengirim panggilan ke pesan suara dengan gerakan yang dikenal — tanpa memikirkan aplikasi mana yang memproses panggilan.
Menurut Apple WWDC 2023 Session “What’s new in CallKit”, lebih dari 85% pengguna lebih memilih aplikasi dengan integrasi CallKit daripada yang menggunakan UI sendiri untuk panggilan. Alasannya — keseragaman dan prediktabilitas kontrol sistem yang tidak memerlukan pembelajaran.
Tanpa CallKit, panggilan VoIP masuk dikirimkan melalui notifikasi push standar. Pengguna melihat banner, mengetuknya, menunggu aplikasi terbuka, dan baru kemudian melihat layar panggilan. CallKit bersama dengan PushKit mempersingkat jalur ini menjadi nol: panggilan muncul seketika, bahkan jika aplikasi tidak dijalankan, dan antarmuka sistem siap menjawab dalam milidetik.
Arsitektur CallKit dibangun di sekitar dua kelas kunci — CXProvider dan CXCallController, yang mengimplementasikan pola provider-klien. Provider mengelola panggilan di sisi sistem, klien memulai tindakan atas nama pengguna atau aplikasi. Pemisahan ini menjamin bahwa antarmuka sistem selalu konsisten, bahkan jika aplikasi untuk sementara tidak tersedia.
CXProvider — objek pusat yang mendaftarkan aplikasi di CallKit sebagai penyedia panggilan. Dikonfigurasi melalui CXProviderConfiguration, di mana ikon aplikasi, jenis panggilan yang didukung (audio, video), dan jumlah maksimum grup simultan ditentukan. Provider menerima permintaan tindakan dari sistem dan meneruskannya ke aplikasi melalui delegasi 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 — objek klien yang digunakan aplikasi untuk meminta tindakan pada panggilan: memulai, mengakhiri, menahan, beralih. Permintaan dikirim ke CallKit melalui CXTransaction, yang berisi array objek CXAction. CallKit memvalidasi setiap tindakan dan menjalankannya jika diizinkan dalam status saat ini.
let controller = CXCallController()
let startCallAction = CXStartCallAction(
callUUID: UUID(),
handle: CXHandle(type: .phoneNumber, value: "+15551234567")
)
startCallAction.isVideo = true
controller.request(CXTransaction(action: startCallAction))
Delegasi provider menerima semua acara dari CallKit. Metode kritis — providerDidBegin, yang menandakan bahwa panggilan telah dimulai. Di provider:performAnswerCallAction aplikasi harus memulai sesi audio: mengaktifkan AVAudioSession dan memulai transmisi media. Jika aplikasi tidak mengaktifkan sesi audio dalam waktu terbatas, CallKit akan mengakhiri panggilan.
PushKit — komponen wajib untuk mengirimkan panggilan VoIP masuk ke CallKit. Notifikasi push biasa (APNs) memiliki latensi yang tidak dapat diprediksi dan tidak menjamin pengiriman jika aplikasi berada di latar belakang. PushKit menggunakan koneksi TCP permanen dengan server Apple untuk pengiriman instan notifikasi VoIP, yang sangat penting untuk panggilan waktu nyata.
Skema kerja: server mengirim notifikasi VoIP melalui PushKit → aplikasi menerimanya di pushRegistry:didReceiveIncomingPushWithPayload → aplikasi segera menampilkan panggilan masuk melalui CXProvider → CallKit menampilkan layar panggilan sistem. Semuanya terjadi dalam sekejap, dan pengguna melihat panggilan bersamaan dengan kedatangannya di server.
Mulai dari iOS 13, Apple menerapkan batasan: notifikasi VoIP harus digunakan hanya untuk indikasi panggilan masuk. Penggunaan PushKit untuk memuat data latar belakang atau memperbarui konten dilarang — aplikasi semacam itu dapat ditolak saat moderasi. Perubahan ini membuat ekosistem VoIP lebih dapat diprediksi, karena semua notifikasi PushKit sekarang dijamin terkait dengan panggilan.
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 — ekstensi aplikasi yang memungkinkan aplikasi menyediakan sistem daftar nomor untuk identifikasi (menampilkan nama penelepon) dan pemblokiran. Ekstensi bekerja secara independen dari aplikasi utama: sistem memuat data dari ekstensi saat aktivasi, dan semua operasi selanjutnya dilakukan tanpa partisipasi aplikasi, menghemat sumber daya dan meningkatkan keamanan.
Ekstensi menggunakan CXCallDirectoryManager untuk mengelola data. Aplikasi melalui proses utama menambahkan nomor ke basis data ekstensi, lalu memanggil reloadExtension untuk memperbarui cache sistem. Apple merekomendasikan pembaruan data tidak lebih dari sekali dalam satu jam untuk menghindari beban sistem yang tidak perlu.
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()
}
}
| Metode CXCallDirectoryManager | Tujuan |
|---|---|
| reloadExtension | Pembaruan paksa cache sistem |
| getEnabledStatus | Memeriksa apakah ekstensi diaktifkan oleh pengguna |
| openSettings | Navigasi ke layar pengaturan ekstensi |
Integrasi CallKit penuh memerlukan konfigurasi tiga komponen: konfigurasi penyedia, pemrosesan panggilan masuk melalui PushKit, dan manajemen sesi audio. Di bawah ini adalah contoh minimal yang berfungsi untuk memproses panggilan VoIP masuk, menampilkannya melalui CallKit, dan mengaktifkan 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 tersedia di iOS, macOS, dan iPadOS, tetapi perilaku framework berbeda antar platform. Di iOS CallKit berfungsi penuh: layar panggilan sistem, layar kunci, integrasi CarPlay. Di iPadOS tampilan panggilan terjadi sebagai banner sistem, bukan antarmuka layar penuh. Di macOS CallKit tersedia sejak macOS 10.14 Mojave, tetapi hanya untuk aplikasi Mac yang dibangun dengan Catalyst atau yang menggunakan AppKit secara langsung.
Keterbatasan utama — CallKit tidak didukung di watchOS. Pengembang Apple Watch tidak dapat menampilkan panggilan VoIP melalui antarmuka sistem di jam tangan. Sebagai gantinya, aplikasi watchOS menerima notifikasi tentang panggilan melalui WCSession dan harus mengimplementasikan layar panggilannya sendiri. CallKit juga tidak berfungsi di simulator — pengujian fungsi VoIP hanya dimungkinkan pada perangkat fisik.
| Fungsi | iOS | iPadOS | macOS |
|---|---|---|---|
| Layar panggilan sistem | Layar penuh | Banner | Banner |
| Layar kunci | Ya | Tidak | Tidak |
| CarPlay | Ya | Tidak | Tidak |
| Call Directory | Ya | Ya | Tidak |
| Riwayat Recents | Ya | Ya | Ya |
Pertanyaan yang sering diajukan
Ya, untuk panggilan masuk PushKit wajib. Hanya PushKit yang menjamin pengiriman instan notifikasi VoIP ke aplikasi yang sedang tidur atau tertutup, yang sangat penting untuk menampilkan panggilan tepat waktu melalui CallKit.
Ya, CallKit mendukung audio dan video. Saat konfigurasi CXProvider atur supportsVideo = true, dan di CXStartCallAction atur isVideo = true. Sistem akan menampilkan ikon kamera dengan benar di antarmuka panggilan.
Tidak bisa — CallKit tidak berfungsi di simulator. Untuk pengujian gunakan perangkat fisik iOS atau iPadOS. Di macOS Anda dapat menguji di Mac asli dengan mikrofon.
Ya, setiap aplikasi mendaftarkan CXProvider masing-masing. Sistem memproses panggilan dari berbagai aplikasi dengan benar dan menampilkannya sebagai panggilan terpisah di Recents. Pengguna melihat dari aplikasi mana panggilan berasal.
CallKit akan secara otomatis mengakhiri panggilan setelah waktu terbatas jika aplikasi tidak mengaktifkan sesi audio. Timer menyala untuk mencegah sistem tetap dalam status panggilan tanpa aliran audio nyata.
Ringkasan
Kami akan mengembangkan aplikasi seluler turnkey
IT Sectr membuat aplikasi iOS dan Android untuk startup dan bisnis sejak 2017. Kami akan memberi saran dan mengusulkan solusi terbaik.
Baca juga