CallKit — فریمورک اپل است که به برنامههای VoIP امکان میدهد تماسهای دریافتی و خروجی را در رابط سیستمی تلفن iOS، از جمله صفحه قفل، نمایش دهند. توسعهدهنده عناصر کنترل استاندارد — قبول، رد، نگه داشتن تماس — را بدون نیاز به ایجاد UI خود دریافت میکند. به گفته Apple Developer Documentation, 2026, این فریمورک تا 98% از تماسهای VoIP را از طریق یک رابط سیستمی واحد پردازش میکند که تکهتکه شدن تجربه کاربری بین پیامرسانها و برنامههای ارتباطی مختلف را از بین میبرد.
نکات اصلی
CallKit — فریمورک اپل است که در iOS 10 معرفی شد و رابط برنامهنویسی برای یکپارچهسازی برنامههای VoIP با برنامه تلفن سیستمی فراهم میکند. قبل از ظهور CallKit هر برنامه VoIP تماس دریافتی را در UI خود نمایش میداد — کاربر اعلانی از برنامه میدید اما نمیتوانست به روش سیستمی پاسخ دهد. CallKit این تجربه را یکپارچه میکند: تماس VoIP دریافتی مانند یک تماس تلفنی معمولی با همان عناصر کنترل نمایش داده میشود.
هدف اصلی CallKit از بین بردن تکهتکه شدن تجربه کاربری است. وقتی برنامه از CallKit استفاده میکند، تماس در صفحه قفل، تاریخچه تماسها و لیست تماسهای اخیر برنامه سیستمی تلفن ظاهر میشود. کاربر میتواند با حرکات آشنا پاسخ دهد، رد کند یا تماس را به پست صوتی بفرستد — بدون اینکه فکر کند کدام برنامه تماس را پردازش میکند.
به گفته Apple WWDC 2023 Session «What’s new in CallKit», بیش از 85% کاربران برنامههای دارای یکپارچهسازی CallKit را به برنامههایی که از UI خود برای تماس استفاده میکنند ترجیح میدهند. دلیل — یکنواختی و قابل پیشبینی بودن عناصر کنترل سیستمی که نیاز به یادگیری ندارند.
بدون CallKit تماس VoIP دریافتی از طریق اعلان استاندارد push تحویل داده میشود. کاربر بنری میبیند، روی آن ضربه میزند، منتظر باز شدن برنامه میماند و تنها بعد از آن صفحه تماس را میبیند. CallKit همراه با PushKit این مسیر را به صفر میرساند: تماس فوراً نمایش داده میشود، حتی اگر برنامه اجرا نشده باشد، و رابط سیستمی در میلیثانیه برای پاسخ آماده است.
معماری CallKit حول دو کلاس کلیدی — CXProvider و CXCallController ساخته شده است که الگوی provider-client را پیادهسازی میکنند. ارائهدهنده تماس را از طرف سیستم مدیریت میکند، کلاینت اقدامات را از طرف کاربر یا برنامه آغاز میکند. این تفکیک تضمین میکند که رابط سیستمی همیشه سازگار باقی میماند، حتی اگر برنامه موقتاً در دسترس نباشد.
CXProvider — شیء مرکزی که برنامه را در CallKit به عنوان ارائهدهنده تماس ثبت میکند. از طریق CXProviderConfiguration پیکربندی میشود، جایی که آیکون برنامه، انواع تماسهای پشتیبانی شده (صوتی، تصویری) و حداکثر تعداد گروههای همزمان مشخص میشود. ارائهدهنده درخواستهای اقدامات را از سیستم دریافت میکند و آنها را از طریق نماینده 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 — شیء کلاینتی که برنامه از طریق آن اقدامات روی تماسها را درخواست میکند: شروع، پایان، نگه داشتن، جابجایی. درخواستها از طریق CXTransaction به CallKit ارسال میشوند که شامل آرایهای از اشیاء CXAction است. CallKit هر اقدام را اعتبارسنجی میکند و در صورت مجاز بودن در وضعیت فعلی آن را اجرا میکند.
let controller = CXCallController()
let startCallAction = CXStartCallAction(
callUUID: UUID(),
handle: CXHandle(type: .phoneNumber, value: "+15551234567")
)
startCallAction.isVideo = true
controller.request(CXTransaction(action: startCallAction))
نماینده ارائهدهنده همه رویدادها را از CallKit دریافت میکند. روش حیاتی — providerDidBegin, که نشان میدهد تماس شروع شده است. در provider:performAnswerCallAction برنامه باید جلسه صوتی را شروع کند: AVAudioSession را فعال کرده و انتقال رسانه را آغاز کند. اگر برنامه در زمان محدودی جلسه صوتی را فعال نکند، CallKit تماس را پایان میدهد.
PushKit — مؤلفه اجباری برای تحویل تماسهای VoIP دریافتی به CallKit. اعلانهای معمولی push (APNs) تأخیر غیرقابل پیشبینی دارند و در صورت پسزمینه بودن برنامه، تحویل را تضمین نمیکنند. PushKit از اتصال دائمی TCP با سرورهای اپل برای تحویل فوری اعلانهای VoIP استفاده میکند که برای تماسهای بلادرنگ حیاتی است.
طرح کار: سرور اعلان VoIP را از طریق PushKit ارسال میکند → برنامه آن را در pushRegistry:didReceiveIncomingPushWithPayload دریافت میکند → برنامه بلافاصله تماس دریافتی را از طریق CXProvider نمایش میدهد → CallKit صفحه تماس سیستمی را نشان میدهد. همه چیز در کسری از ثانیه اتفاق میافتد و کاربر تماس را همزمان با رسیدن آن به سرور میبیند.
از iOS 13 به بعد، اپل محدودیتی اعمال کرد: اعلانهای VoIP باید فقط برای نشان دادن تماسهای دریافتی استفاده شوند. استفاده از PushKit برای بارگذاری دادههای پسزمینه یا بهروزرسانی محتوا ممنوع است — چنین برنامههایی ممکن است در بازبینی رد شوند. این تغییر اکوسیستم VoIP را قابل پیشبینیتر کرد، زیرا همه اعلانهای PushKit اکنون تضمیناً با تماسها مرتبط هستند.
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 — افزونه برنامه که به برنامه امکان میدهد لیستهای شمارهها را برای شناسایی (نمایش نام تماسگیرنده) و مسدودسازی در اختیار سیستم قرار دهد. افزونه مستقل از برنامه اصلی کار میکند: سیستم دادهها را از افزونه در هنگام فعالسازی بارگذاری میکند و تمام عملیات بعدی بدون مشارکت برنامه انجام میشود که باعث صرفهجویی در منابع و افزایش امنیت میشود.
افزونه از CXCallDirectoryManager برای مدیریت دادهها استفاده میکند. برنامه از طریق فرآیند اصلی شمارهها را به پایگاه داده افزونه اضافه میکند و سپس reloadExtension را برای بهروزرسانی کش سیستمی فراخوانی میکند. اپل توصیه میکند دادهها را بیشتر از هر ساعت یک بار بهروز نکنید تا از بار اضافی روی سیستم جلوگیری شود.
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 | کاربرد |
|---|---|
| reloadExtension | بهروزرسانی اجباری کش سیستم |
| getEnabledStatus | بررسی فعال بودن افزونه توسط کاربر |
| openSettings | رفتن به صفحه تنظیمات افزونه |
یکپارچهسازی کامل CallKit نیاز به پیکربندی سه مؤلفه دارد: پیکربندی ارائهدهنده، پردازش تماسهای دریافتی از طریق PushKit و مدیریت جلسه صوتی. در زیر یک نمونه حداقلی کارآمد ارائه شده است که تماس VoIP دریافتی را پردازش میکند، آن را از طریق CallKit نمایش میدهد و صدا را فعال میکند.
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 در iOS, macOS و iPadOS در دسترس است، اما رفتار فریمورک بین پلتفرمها متفاوت است. در iOS CallKit به طور کامل کار میکند: صفحه تماس سیستمی، صفحه قفل، یکپارچهسازی با CarPlay. در iPadOS نمایش تماس به صورت بنر سیستمی انجام میشود نه رابط تمام صفحه. در macOS CallKit از macOS 10.14 Mojave در دسترس است، اما فقط برای برنامههای Mac ساخته شده با Catalyst یا استفاده مستقیم از AppKit.
محدودیت کلیدی — CallKit در watchOS پشتیبانی نمیشود. توسعهدهندگان Apple Watch نمیتوانند تماسهای VoIP را از طریق رابط سیستمی روی ساعت نمایش دهند. در عوض، برنامه watchOS اعلانی درباره تماس از طریق WCSession دریافت میکند و باید صفحه تماس خود را پیادهسازی کند. همچنین CallKit روی شبیهساز کار نمیکند — آزمایش عملکردهای VoIP فقط روی دستگاه فیزیکی امکانپذیر است.
| قابلیت | iOS | iPadOS | macOS |
|---|---|---|---|
| صفحه تماس سیستمی | تمام صفحه | بنر | بنر |
| صفحه قفل | بله | خیر | خیر |
| CarPlay | بله | خیر | خیر |
| Call Directory | بله | بله | خیر |
| تاریخچه Recents | بله | بله | بله |
سؤالات متداول
بله، برای تماسهای دریافتی PushKit اجباری است. فقط PushKit تحویل فوری اعلان VoIP را به برنامه خواب یا بسته تضمین میکند که برای نمایش به موقع تماس از طریق CallKit حیاتی است.
بله، CallKit از صوت و تصویر پشتیبانی میکند. در پیکربندی CXProvider supportsVideo = true و در CXStartCallAction isVideo = true را تنظیم کنید. سیستم آیکون دوربین را در رابط تماس به درستی نمایش میدهد.
به هیچ وجه — CallKit روی شبیهساز کار نمیکند. برای تست از دستگاه فیزیکی iOS یا iPadOS استفاده کنید. در macOS میتوانید روی Mac واقعی با میکروفون تست کنید.
بله، هر برنامه CXProvider خود را ثبت میکند. سیستم تماسها از برنامههای مختلف را به درستی پردازش میکند و آنها را به عنوان تماسهای جداگانه در Recents نمایش میدهد. کاربر میبیند تماس از کدام برنامه آمده است.
CallKit به طور خودکار تماس را پایان میدهد پس از مدت زمان محدود اگر برنامه جلسه صوتی را فعال نکند. تایمر فعال میشود تا سیستم در حالت تماس بدون جریان صوتی واقعی باقی نماند.
خلاصه
ما یک اپلیکیشن موبایل به صورت کلید در دست توسعه خواهیم داد
IT Sectr از سال 2017 برنامههای iOS و Android را برای استارتاپها و کسبوکارها ایجاد میکند. ما به شما مشاوره میدهیم و بهترین راهحل را پیشنهاد خواهیم کرد.
همچنین بخوانید