PushKit là một framework của Apple để gửi thông báo push với phương thức giao ngay lập tức được đảm bảo, được thiết kế chủ yếu cho các ứng dụng VoIP. Không giống như APNs tiêu chuẩn (Apple Push Notification service), có thể bị trễ hoặc gộp lại, PushKit sử dụng kết nối TCP liên tục giữa thiết bị và máy chủ của Apple. Theo Apple Developer Documentation, 2026, PushKit cung cấp độ trễ giao hàng đầu-cuối dưới 500 mili giây, điều này rất quan trọng đối với các ứng dụng thời gian thực — cuộc gọi thoại và video.
Điểm chính
PushKit là một framework của Apple được giới thiệu trong iOS 8, cung cấp cơ chế gửi thông báo push với ưu tiên được đảm bảo thông qua kết nối liên tục với máy chủ APNs. Không giống như các thông báo thông thường đi qua một kênh APNs duy nhất và có thể bị trễ, các thông báo PushKit sử dụng một luồng chuyên dụng với ưu tiên cao hơn, đảm bảo giao hàng gần như thời gian thực.
Về mặt kỹ thuật, PushKit hoạt động thông qua kết nối TCP liên tục giữa thiết bị và máy chủ push của Apple. Khi một máy chủ gửi thông báo VoIP, kết nối sẽ ngay lập tức chuyển nó đến thiết bị, thiết bị sẽ đánh thức ứng dụng và gọi ủy quyền PKPushRegistry. Ứng dụng không cần ở trạng thái hoạt động — PushKit có thể đánh thức nó từ nền, trạng thái đã kết thúc hoặc thậm chí sau khi khởi động lại thiết bị.
Theo nghiên cứu của Microsoft Research (2024) về độ trễ thông báo push trên các nền tảng di động, độ trễ trung vị của thông báo PushKit là 120–350 ms, trong khi thông báo APNs tiêu chuẩn có trung vị là 1–5 giây. Sự khác biệt về cấp độ độ lớn được giải thích bởi kênh TCP chuyên dụng và xử lý ưu tiên tại phía Apple.
PushKit hỗ trợ bốn loại: VoIP (cho cuộc gọi), Complication (cho dữ liệu mặt đồng hồ), FileProvider (cho đồng bộ tập tin) và PushToTalk (cho chức năng bộ đàm). Kể từ iOS 13, chỉ có loại VoIP vẫn khả dụng rộng rãi cho các nhà phát triển bên thứ ba. Complication và FileProvider có ứng dụng chuyên biệt và bị giới hạn trong hệ sinh thái riêng của Apple.
| Loại PushKit | Mục đích | Khả dụng |
|---|---|---|
| VoIP | Chỉ báo cuộc gọi thoại và video đến | iOS 8+, App Store |
| Complication | Cập nhật dữ liệu trên mặt đồng hồ Apple Watch | watchOS 6+ |
| FileProvider | Tín hiệu về tập tin mới trong File Provider Extension | iOS 11+, hạn chế |
| PushToTalk | Chức năng bộ đàm trong ứng dụng doanh nghiệp | iOS 16+, truy cập hạn chế |
APNs (Apple Push Notification service) là một dịch vụ gửi thông báo push phổ quát hoạt động thông qua một kênh duy nhất cho tất cả các ứng dụng. Apple có thể đệm, gộp hoặc thậm chí loại bỏ các thông báo APNs khi kênh bị tắc nghẽn. Mặt khác, PushKit sử dụng kết nối chuyên dụng cho mỗi loại thông báo và Apple đảm bảo giao hàng mỗi push VoIP mà không có đệm.
Sự khác biệt trở nên rõ ràng trong các kịch bản quan trọng về thời gian: một cuộc gọi đến được gửi qua APNs có thể đến với độ trễ 10–30 giây hoặc không đến nếu thiết bị ở chế độ tiết kiệm năng lượng. PushKit gửi cùng một thông báo trong 100–500 ms bất kể trạng thái thiết bị, vì kênh TCP của nó được hệ thống duy trì hoạt động với ưu tiên.
| Thông số | PushKit | APNs |
|---|---|---|
| Loại kết nối | TCP liên tục (kênh chuyên dụng) | Kênh chia sẻ có đệm |
| Độ trễ trung vị | 120–350 ms | 1–5 giây |
| Đánh thức ứng dụng | Luôn luôn, từ bất kỳ trạng thái nào | Chỉ nếu ứng dụng chưa bị tắt |
| Kích thước payload | Tối đa 5 KB | Tối đa 4 KB |
| Gộp iOS | Không | Có |
Kiến trúc PushKit được xây dựng xoay quanh PKPushRegistry — một đối tượng đăng ký ứng dụng để nhận thông báo của một loại cụ thể. Ứng dụng tạo một thể hiện PKPushRegistry, chỉ định loại mong muốn (ví dụ: PKPushTypeVoIP) và chỉ định một ủy quyền. Sau khi đăng ký, hệ thống tự động duy trì kết nối với APNs và gửi thông báo push thông qua ủy quyền.
Mỗi thông báo được đại diện bởi một đối tượng PKPushPayload, chứa dictionaryPayload với dữ liệu từ máy chủ. Kích thước payload được giới hạn ở 5 KB, đủ để truyền siêu dữ liệu cuộc gọi: mã nhận dạng người gọi, loại cuộc gọi (âm thanh/video), tên liên hệ và token phiên. Luồng phương tiện được truyền riêng qua WebRTC hoặc một giao thức thời gian thực khác.
import PushKit
class PushKitManager: NSObject {
private let pushRegistry = PKPushRegistry(queue: .main)
func configure() {
pushRegistry.delegate = self
pushRegistry.desiredPushTypes = [.voIP]
}
}
PushKit gọi phương thức ủy quyền khi nhận được thông báo. Tại thời điểm này, ứng dụng phải trích xuất dữ liệu từ dictionaryPayload và hiển thị ngay cuộc gọi qua CallKit, nếu không hệ thống có thể kết thúc tác vụ nền. Apple khuyến nghị hoàn tất xử lý trong vòng 30 giây, nhưng đối với cuộc gọi VoIP, việc hiển thị màn hình cuộc gọi trong giây đầu tiên là rất quan trọng.
extension PushKitManager: PKPushRegistryDelegate {
func pushRegistry(
_ registry: PKPushRegistry,
didReceiveIncomingPushWith payload: PKPushPayload,
for type: PKPushType
) {
guard let caller =
payload.dictionaryPayload["caller"] as? String
else { return }
CallKitManager.shared.reportIncomingCall(
uuid: UUID(),
handle: caller
)
}
}
Với việc phát hành iOS 13, Apple đã đưa ra các hạn chế nghiêm ngặt đối với việc sử dụng PushKit. Các nhà phát triển đã sử dụng rộng rãi VoIP push như một cơ chế ẩn để cập nhật ứng dụng nền — đánh thức qua PushKit cho phép tải nội dung, đồng bộ dữ liệu và cập nhật giao diện mà không có sự cho phép rõ ràng của người dùng. Apple coi đây là hành vi vi phạm khái niệm tiết kiệm năng lượng và giới hạn PushKit chỉ dành cho chỉ báo cuộc gọi đến.
Giờ đây, mỗi thông báo PushKit phải ngay lập tức dẫn đến việc hiển thị cuộc gọi đến qua CallKit. Nếu hệ thống phát hiện PushKit được sử dụng cho các mục đích khác — ví dụ, đồng bộ nền hoặc cập nhật nội dung mà không hiển thị cuộc gọi — ứng dụng có thể bị từ chối khi xem xét hoặc bị vô hiệu hóa khỏi dịch vụ PushKit. Apple cũng đã loại bỏ khả năng sử dụng PushKit để cập nhật dữ liệu nền kể từ iOS 13.
Tích hợp PushKit đầy đủ bao gồm đăng ký, lấy token push và xử lý các thông báo đến. PushKit tự động yêu cầu quyền gửi thông báo — không cần gọi thêm UNUserNotificationCenter cho riêng PushKit, nhưng có thể cần cho các thông báo cục bộ của ứng dụng. Sau khi đăng ký, hệ thống gọi pushRegistry:didUpdatePushCredentials để gửi token push, token này cần được gửi đến máy chủ.
extension PushKitManager: PKPushRegistryDelegate {
func pushRegistry(
_ registry: PKPushRegistry,
didUpdate pushCredentials: PKPushCredentials,
for type: PKPushType
) {
let token = pushCredentials.token
.map { String(format: "%02x", $0) }
.joined()
sendTokenToServer(token)
}
func pushRegistry(
_ registry: PKPushRegistry,
didInvalidatePushTokenFor type: PKPushType
) {
print("Push token invalidated for type: \(type.rawValue)")
}
}
Phía máy chủ gửi thông báo PushKit qua APNs với push-type = voip và tiêu đề apns-push-type: voip. Không giống như APNs thông thường, VoIP push sử dụng chứng chỉ riêng và không yêu cầu cấu hình topic. Payload phải chứa dữ liệu tối thiểu để xác định cuộc gọi.
// Ví dụ về payload push VoIP
{
"aps": {
"alert": {}
},
"caller": "+15551234567",
"callerName": "Alice Johnson",
"sessionId": "abc-123-def",
"hasVideo": false
}
Việc gỡ lỗi PushKit phức tạp hơn APNs tiêu chuẩn vì PushKit không hoạt động trên trình mô phỏng iOS. Cần có iPhone hoặc iPad thật để chẩn đoán. Dấu hiệu đầu tiên của hoạt động chính xác là lời gọi pushRegistry:didUpdatePushCredentials khi khởi chạy và sự xuất hiện của token push ở định dạng cụ thể (64 ký tự hex cho VoIP). Nếu ủy quyền không được gọi, hãy kiểm tra entitlements của ứng dụng của bạn.
Một vấn đề phổ biến khác là PushKit không gửi thông báo sau khi cập nhật ứng dụng. Điều này xảy ra nếu token push đã thay đổi nhưng máy chủ vẫn tiếp tục sử dụng token cũ. Giải pháp là gửi token mới đến máy chủ khi khởi chạy ứng dụng và xóa các token không hợp lệ khi pushRegistry:didInvalidatePushTokenForType được gọi. Apple cũng khuyến nghị triển khai cơ chế dự phòng qua APNs thông thường.
| Vấn đề | Nguyên nhân | Giải pháp |
|---|---|---|
| Không gọi được didUpdatePushCredentials | Thiếu entitlements hoặc sai loại | Kiểm tra Capabilities → Push Notifications + VoIP trong Xcode |
| Push đến bị trễ | Thiết bị ở chế độ năng lượng thấp hoặc tín hiệu yếu | PushKit không thể vượt qua các giới hạn phần cứng |
| Không nhận được thông báo sau khi khởi động lại | Token push đã thay đổi sau khi cài đặt lại ứng dụng | Yêu cầu token mới và cập nhật nó trên máy chủ |
| App Store từ chối vì PushKit | PushKit được sử dụng cho mục đích không phải cuộc gọi | Đảm bảo mỗi push dẫn đến reportNewIncomingCall |
Câu hỏi thường gặp
Về mặt kỹ thuật là có, nhưng sẽ vô ích. Kể từ iOS 13, cách sử dụng PushKit duy nhất được phép là chỉ báo cuộc gọi đến, yêu cầu CallKit để hiển thị. Sử dụng PushKit mà không có CallKit sẽ dẫn đến việc ứng dụng bị từ chối trên App Store.
Kích thước payload tối đa cho PushKit là 5 KB (5120 byte). Nhiều hơn 1 KB so với thông báo APNs thông thường, cho phép truyền nhiều siêu dữ liệu cuộc gọi hơn.
Apple tự động vô hiệu hóa token push khi ứng dụng bị xóa. Máy chủ sẽ nhận được thông báo vô hiệu hóa và phải ngừng gửi push đến token đó. Cố gắng gửi push đến token không hợp lệ sẽ dẫn đến lỗi APNs 410.
PushKit khả dụng trên macOS 10.14+ cho các ứng dụng Mac được xây dựng bằng Mac Catalyst hoặc AppKit. Chức năng hoàn toàn tương đương với phiên bản iOS, bao gồm hỗ trợ thông báo VoIP.
Sử dụng phân tích riêng của bạn: theo dõi thời gian giữa việc gửi push từ máy chủ và lời gọi didReceiveIncomingPushWithPayload trên máy khách. Thời gian trung bình dưới 500 ms cho thấy PushKit hoạt động chính xác.
Tổng kết
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.
Đọc thêm