CallKit: nó là gì, framework VoIP và tích hợp với điện thoại hệ thống

Tác giả: IT Sectr Đã đăng: 2026-06-16 Thời gian đọc: 9 phút

CallKit là một framework của Apple cho phép các ứng dụng VoIP hiển thị cuộc gọi đến và đi trong giao diện điện thoại hệ thống iOS, bao gồm màn hình khóa. Nhà phát triển nhận được các điều khiển tiêu chuẩn — chấp nhận, từ chối, giữ cuộc gọi — mà không cần tạo giao diện người dùng riêng. Theo Apple Developer Documentation, 2026, framework xử lý tới 98% cuộc gọi VoIP thông qua một giao diện hệ thống duy nhất, loại bỏ sự phân mảnh trải nghiệm người dùng giữa các ứng dụng nhắn tin và liên lạc khác nhau.

Những điểm chính

  • CallKit — framework tích hợp cuộc gọi VoIP vào ứng dụng Điện thoại hệ thống trên iOS, macOS và iPadOS.
  • CXProvider — lớp chính để quản lý cuộc gọi: bắt đầu, kết thúc, giữ và chuyển đổi giữa các cuộc gọi.
  • CXCallController — giao diện khách hàng để thực hiện cuộc gọi đi và yêu cầu hành động trên các cuộc gọi hiện tại.
  • Call Directory Extension — phần mở rộng để xác định và chặn số đến ở cấp hệ thống.
  • PushKit — người bạn đồng hành thiết yếu của CallKit: gửi thông báo VoIP đến mà không chậm trễ để hiển thị cuộc gọi tức thì.

CallKit là gì và tại sao cần nó?

CallKit là framework của Apple được giới thiệu trong iOS 10 cung cấp giao diện lập trình để tích hợp ứng dụng VoIP với ứng dụng Điện thoại hệ thống. Trước CallKit, mỗi ứng dụng VoIP hiển thị cuộc gọi đến trong giao diện người dùng riêng — người dùng thấy thông báo từ ứng dụng nhưng không thể trả lời theo cách hệ thống. CallKit hợp nhất trải nghiệm này: cuộc gọi VoIP đến hiển thị như cuộc gọi điện thoại thông thường với các điều khiển tương tự.

Mục đích chính của CallKit là loại bỏ sự phân mảnh trải nghiệm người dùng. Khi ứng dụng sử dụng CallKit, cuộc gọi xuất hiện trên màn hình khóa, trong lịch sử cuộc gọi và trong danh sách cuộc gọi gần đây của ứng dụng Điện thoại hệ thống. Người dùng có thể trả lời, từ chối hoặc gửi cuộc gọi đến hộp thư thoại bằng các thao tác quen thuộc — mà không cần suy nghĩ ứng dụng nào đang xử lý cuộc gọi.

Theo phiên Apple WWDC 2023 “What’s new in CallKit”, hơn 85% người dùng thích ứng dụng có tích hợp CallKit hơn những ứng dụng sử dụng giao diện người dùng riêng cho cuộc gọi. Lý do là sự nhất quán và khả năng dự đoán của các điều khiển hệ thống không yêu cầu học tập.

CallKit thay đổi trải nghiệm người dùng VoIP như thế nào

Không có CallKit, cuộc gọi VoIP đến được gửi qua thông báo push tiêu chuẩn. Người dùng thấy banner, chạm vào nó, chờ ứng dụng mở và chỉ sau đó mới thấy màn hình cuộc gọi. CallKit cùng với PushKit giảm đường dẫn này xuống bằng không: cuộc gọi xuất hiện ngay lập tức, ngay cả khi ứng dụng không chạy và giao diện hệ thống sẵn sàng trả lời trong mili giây.

  • Cuộc gọi xuất hiện trên màn hình khóa và luôn hiển thị phía trên các ứng dụng khác
  • Các hành động tiêu chuẩn được hỗ trợ: trả lời, từ chối, nhắc nhở, trả lời bằng tin nhắn
  • Tích hợp CarPlay — cuộc gọi xuất hiện trên màn hình xe hơi
  • Tự động ghi vào danh sách Gần đây và lịch sử cuộc gọi hệ thống

Kiến trúc CallKit: CXProvider và CXCallController

Kiến trúc CallKit được xây dựng xung quanh hai lớp chính — CXProviderCXCallController, triển khai mô hình nhà cung cấp-khách hàng. Nhà cung cấp quản lý cuộc gọi ở phía hệ thống, trong khi khách hàng khởi tạo hành động thay mặt người dùng hoặc ứng dụng. Sự tách biệt này đảm bảo giao diện hệ thống luôn nhất quán, ngay cả khi ứng dụng tạm thời không khả dụng.

CXProvider — nhà cung cấp cuộc gọi

CXProvider là đối tượng trung tâm đăng ký ứng dụng trong CallKit như một nhà cung cấp cuộc gọi. Nó được cấu hình qua CXProviderConfiguration, nơi chỉ định biểu tượng ứng dụng, loại cuộc gọi được hỗ trợ (âm thanh, video) và số lượng nhóm đồng thời tối đa. Nhà cung cấp nhận yêu cầu hành động từ hệ thống và chuyển chúng đến ứng dụng qua CXProviderDelegate.

swift
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 — quản lý cuộc gọi

CXCallController là đối tượng khách hàng qua đó ứng dụng yêu cầu hành động trên cuộc gọi: bắt đầu, kết thúc, giữ, chuyển đổi. Yêu cầu được gửi đến CallKit qua CXTransaction, chứa một mảng các đối tượng CXAction. CallKit xác thực từng hành động và thực hiện nếu được phép trong trạng thái hiện tại.

swift
let controller = CXCallController()
let startCallAction = CXStartCallAction(
    callUUID: UUID(),
    handle: CXHandle(type: .phoneNumber, value: "+15551234567")
)
startCallAction.isVideo = true
controller.request(CXTransaction(action: startCallAction))

CXProviderDelegate — xử lý sự kiện

Ủy quyền của nhà cung cấp nhận tất cả sự kiện từ CallKit. Phương thức quan trọng là providerDidBegin, báo hiệu cuộc gọi đã bắt đầu. Trong provider:performAnswerCallAction, ứng dụng phải bắt đầu phiên âm thanh: kích hoạt AVAudioSession và bắt đầu truyền phương tiện. Nếu ứng dụng không kích hoạt phiên âm thanh trong thời gian giới hạn, CallKit sẽ kết thúc cuộc gọi.

  • providerDidBegin — cuộc gọi bắt đầu, chuẩn bị âm thanh
  • provider:performAnswerCallAction — người dùng đã trả lời, cần kích hoạt AVAudioSession
  • provider:performEndCallAction — cuộc gọi kết thúc, dừng phương tiện
  • provider:performSetMutedCallAction — chuyển đổi micrô

Tích hợp PushKit với CallKit cho cuộc gọi đến

PushKit là thành phần bắt buộc để gửi cuộc gọi VoIP đến CallKit. Thông báo push thông thường (APNs) có độ trễ không thể dự đoán và không đảm bảo gửi nếu ứng dụng ở chế độ nền. PushKit sử dụng kết nối TCP liên tục với máy chủ Apple để gửi thông báo VoIP tức thì, điều này rất quan trọng cho cuộc gọi thời gian thực.

Luồng công việc: máy chủ gửi thông báo VoIP qua PushKit → ứng dụng nhận nó trong pushRegistry:didReceiveIncomingPushWithPayload → ứng dụng ngay lập tức hiển thị cuộc gọi đến qua CXProvider → CallKit hiển thị màn hình cuộc gọi hệ thống. Mọi thứ xảy ra trong tích tắc và người dùng thấy cuộc gọi cùng lúc nó đến máy chủ.

Bắt đầu từ iOS 13, Apple đã đưa ra hạn chế: thông báo VoIP chỉ được sử dụng để chỉ báo cuộc gọi đến. Việc sử dụng PushKit để tải dữ liệu nền hoặc cập nhật nội dung bị cấm — các ứng dụng như vậy có thể bị từ chối khi kiểm duyệt. Thay đổi này làm cho hệ sinh thái VoIP dễ dự đoán hơn vì tất cả thông báo PushKit hiện được đảm bảo liên quan đến cuộc gọi.

Ví dụ xử lý thông báo PushKit đến

swift
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: chặn và xác định số

Call Directory Extension là phần mở rộng ứng dụng cho phép ứng dụng cung cấp cho hệ thống danh sách số để xác định (hiển thị tên người gọi) và chặn. Phần mở rộng hoạt động độc lập với ứng dụng chính: hệ thống tải dữ liệu từ phần mở rộng khi kích hoạt và tất cả các thao tác tiếp theo được thực hiện mà không có sự tham gia của ứng dụng, tiết kiệm tài nguyên và tăng cường bảo mật.

Phần mở rộng sử dụng CXCallDirectoryManager để quản lý dữ liệu. Ứng dụng qua tiến trình chính thêm số vào cơ sở dữ liệu của phần mở rộng, sau đó gọi reloadExtension để cập nhật bộ nhớ đệm hệ thống. Apple khuyến nghị cập nhật dữ liệu không quá một lần mỗi giờ để tránh tải không cần thiết lên hệ thống.

Ví dụ triển khai Call Directory Extension

swift
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()
    }
}
Phương thức CXCallDirectoryManagerMục đích
reloadExtensionCập nhật bộ nhớ đệm hệ thống bắt buộc
getEnabledStatusKiểm tra xem phần mở rộng có được người dùng bật không
openSettingsChuyển đến màn hình cài đặt phần mở rộng

Ví dụ tích hợp CallKit trong Swift

Tích hợp CallKit đầy đủ yêu cầu thiết lập ba thành phần: cấu hình nhà cung cấp, xử lý cuộc gọi đến qua PushKit và quản lý phiên âm thanh. Dưới đây là ví dụ hoạt động tối thiểu xử lý cuộc gọi VoIP đến, hiển thị nó qua CallKit và kích hoạt âm thanh.

swift
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()
    }
}

Hạn chế và tính năng của CallKit trên các nền tảng khác nhau

CallKit có sẵn trên iOS, macOS và iPadOS, nhưng hành vi của framework khác nhau giữa các nền tảng. Trên iOS, CallKit hoạt động đầy đủ: màn hình cuộc gọi hệ thống, màn hình khóa, tích hợp CarPlay. Trên iPadOS, cuộc gọi được hiển thị dưới dạng banner hệ thống thay vì giao diện toàn màn hình. Trên macOS, CallKit có sẵn từ macOS 10.14 Mojave, nhưng chỉ cho ứng dụng Mac được xây dựng với Catalyst hoặc sử dụng AppKit trực tiếp.

Hạn chế chính — CallKit không được hỗ trợ trên watchOS. Nhà phát triển Apple Watch không thể hiển thị cuộc gọi VoIP qua giao diện hệ thống trên đồng hồ. Thay vào đó, ứng dụng watchOS nhận thông báo cuộc gọi qua WCSession và phải tự triển khai màn hình cuộc gọi riêng. Ngoài ra, CallKit không hoạt động trên trình giả lập — thử nghiệm tính năng VoIP chỉ khả thi trên thiết bị vật lý.

So sánh CallKit trên iOS, iPadOS và macOS

Tính năngiOSiPadOSmacOS
Màn hình cuộc gọi hệ thốngToàn màn hìnhBannerBanner
Màn hình khóaKhôngKhông
CarPlayKhôngKhông
Danh bạ cuộc gọiKhông
Lịch sử gần đây

Câu hỏi thường gặp

Có bắt buộc phải sử dụng PushKit cùng với CallKit không?

Có, đối với cuộc gọi đến, PushKit là bắt buộc. Chỉ PushKit mới đảm bảo gửi thông báo VoIP tức thì đến ứng dụng đang ngủ hoặc đã đóng, điều này rất quan trọng để hiển thị cuộc gọi kịp thời qua CallKit.

Có thể sử dụng CallKit cho cuộc gọi video không?

Có, CallKit hỗ trợ âm thanh và video. Khi cấu hình CXProvider, đặt supportsVideo = true và trong CXStartCallAction đặt isVideo = true. Hệ thống sẽ hiển thị chính xác biểu tượng camera video trong giao diện cuộc gọi.

Làm thế nào để kiểm tra CallKit mà không có thiết bị vật lý?

Không có cách nào — CallKit không hoạt động trên trình giả lập. Để kiểm tra, hãy sử dụng thiết bị iOS hoặc iPadOS vật lý. Trên macOS, bạn có thể kiểm tra trên Mac thật có micrô.

Hai ứng dụng có thể sử dụng CallKit cùng lúc không?

Có, mỗi ứng dụng đăng ký CXProvider riêng. Hệ thống xử lý chính xác cuộc gọi từ các ứng dụng khác nhau và hiển thị chúng dưới dạng cuộc gọi riêng biệt trong danh sách Gần đây. Người dùng có thể thấy cuộc gọi đến từ ứng dụng nào.

Điều gì xảy ra nếu không kích hoạt AVAudioSession sau khi trả lời cuộc gọi?

CallKit sẽ tự động kết thúc cuộc gọi sau một thời gian giới hạn nếu ứng dụng không kích hoạt phiên âm thanh. Bộ đếm thời gian hoạt động để hệ thống không ở trạng thái cuộc gọi mà không có luồng âm thanh thực.

Tổng kết

  • CallKit — framework Apple để tích hợp cuộc gọi VoIP vào ứng dụng Điện thoại hệ thống trên iOS, iPadOS và macOS, có sẵn từ iOS 10.
  • CXProviderCXCallController — các lớp chính của kiến trúc CallKit, triển khai mô hình nhà cung cấp-khách hàng để quản lý cuộc gọi.
  • PushKit — người bạn đồng hành thiết yếu của CallKit để gửi thông báo VoIP đến tức thì, hoạt động qua kết nối TCP liên tục.
  • Call Directory Extension cho phép chặn và xác định số ở cấp hệ thống, hữu ích cho ứng dụng chống thư rác.
  • CallKit không được hỗ trợ trên watchOS và không hoạt động trên trình giả lập — thử nghiệm tính năng VoIP yêu cầu thiết bị vật lý.
  • Hành vi của CallKit khác nhau giữa các nền tảng: trên iOS — giao diện toàn màn hình, trên iPadOS và macOS — banner hệ thống.
  • Kích hoạt AVAudioSession sau khi trả lời cuộc gọi là bắt buộc — nếu không, CallKit sẽ kết thúc cuộc gọi do hết thời gian chờ.

Chúng tôi sẽ phát triển ứng dụng di động chìa khóa trao tay

IT Sectr tạo các ứng dụng iOS và Android cho các công ty khởi nghiệp và doanh nghiệp từ năm 2017. Chúng tôi sẽ tư vấn và đề xuất giải pháp tốt nhất cho bạn.

Thảo luận dự án

Đọc thêm