PushKit — 这是什么,用于 VoIP 的 push 通知框架

作者: IT Sectr 发布日期: 2026-06-16 阅读时间: 8 分钟

PushKit 是 Apple 的一个框架,用于提供保证即时传递的 push 通知,主要针对 VoIP 应用程序。与标准的 APNs(Apple Push Notification service)不同,它们可能会延迟或被分组,而 PushKit 使用设备与 Apple 服务器之间的永久 TCP 连接。据 Apple Developer Documentation, 2026PushKit 确保传递延迟低于 500 毫秒,这对于实时应用程序 — 语音和视频通话至关重要。

主要要点

  • PushKit — 用于 VoIP、Location 和 FileProvider 类型的高优先级 push 通知传递框架。
  • PKPushRegistry — 用于注册通知类型和接收入局 push 消息的主要类。
  • VoIP-push — 从 iOS 13 开始唯一允许的 PushKit 使用类型,确保入局通话的即时指示。
  • 永久 TCP 连接 — PushKit 的技术基础,保证无 APNs 特有的延迟传递。
  • 与 CallKit 配合 — PushKit 传递通知,CallKit 显示系统通话屏幕,提供统一的用户体验。

PushKit 是什么以及它如何工作?

PushKit 是 Apple 的框架,在 iOS 8 中引入,通过与 APNs 服务器的永久连接提供保证优先级的 push 通知传递机制。与普通通知不同,它们通过单一的 APNs 频道并可能延迟,而 PushKit 通知使用专用的更高优先级流,确保几乎实时传递。

从技术上讲,PushKit 通过设备与 Apple push 服务器之间的永久 TCP 连接工作。当服务器发送 VoIP 通知时,连接立即将其传输到设备,设备唤醒应用程序并调用 PKPushRegistry 委托人。应用程序不需要处于活动状态 — PushKit 可以从后台、终止状态甚至设备重启后唤醒它。

Microsoft Research(2024)关于移动平台上 push 通知延迟的研究,PushKit 通知的中位数延迟为 120–350 毫秒,而标准 APNs 通知的中位数为 1–5 秒。数量级的差异正是由专用 TCP 频道和 Apple 端的优先级处理解释的。

PushKit 支持哪些类型的通知

PushKit 支持四种类型:VoIP(用于通话)、Complication(用于 watchOS 表盘数据)、FileProvider(用于文件同步)和 PushToTalk(用于对讲机功能)。从 iOS 13 开始,只有 VoIP 类型仍然对第三方开发者广泛可用。Complication 和 FileProvider 具有窄专业应用,并且受限于 Apple 自己的生态系统。

PushKit 类型用途可用性
VoIP指示入局语音和视频通话iOS 8+,App Store
Complication更新 Apple Watch 表盘上的数据watchOS 6+
FileProvider关于 File Provider Extension 中新文件的信号iOS 11+,受限
PushToTalk企业应用程序中的对讲机功能iOS 16+,受限访问

PushKit vs APNs:主要差异

APNs(Apple Push Notification service)— 通用的 push 通知传递服务,通过单一频道为所有应用程序工作。当频道负荷过重时,Apple 可以缓冲、分组甚至丢弃 APNs 通知。相反,PushKit 为每种通知类型使用专用连接,Apple 保证无缓冲地传递每个 VoIP-push。

差异在时间关键场景中显现:通过 APNs 传递的入局通话可能会延迟 10–30 秒,如果设备处于节能模式则可能完全不到达。PushKit 无论设备状态如何,都在 100–500 毫秒内传递相同的通知,因为它的 TCP 频道由系统按优先级保持活跃。

特性比较

参数PushKitAPNs
连接类型永久 TCP(专用频道)共享频道带缓冲
中位数延迟120–350 毫秒1–5 秒
唤醒应用程序始终,从任何状态仅当应用程序未终止
载荷大小最大 5 KB最大 4 KB
iOS 分组

PushKit 架构:PKPushRegistry 和 PKPushPayload

PushKit 架构是围绕PKPushRegistry建立的 — 该对象将应用程序注册为接收特定类型的通知。应用程序创建 PKPushRegistry 实例,指定所需类型(例如 PKPushTypeVoIP)并分配委托人。注册后,系统自动保持与 APNs 的连接,并通过委托人传递 push 通知。

每个通知由PKPushPayload对象表示,该对象包含来自服务器的 dictionaryPayload 字典。载荷大小限制为 5 KB,足以传输通话元数据:叫叫人标识符、通话类型(音频/视频)、联系人姓名和会话 token。媒体流通过 WebRTC 或其他实时协议单独传输。

注册 PKPushRegistry

swift
import PushKit

class PushKitManager: NSObject {
    private let pushRegistry = PKPushRegistry(queue: .main)
    
    func configure() {
        pushRegistry.delegate = self
        pushRegistry.desiredPushTypes = [.voIP]
    }
}

接收和处理 push 通知

PushKit 在接收到通知时调用委托方法。此时,应用程序必须从 dictionaryPayload 中提取数据并立即通过 CallKit 显示通话,否则系统可能终止后台任务。Apple 建议在 30 秒内完成处理,但对于 VoIP 通话,在第一秒之内显示通话屏幕至关重要。

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

iOS 13 的限制和 PushKit 使用规则

随着 iOS 13 的发布,Apple 对 PushKit 的使用引入了严格的限制。开发者大量使用 VoIP-push 作为后台更新应用程序的隐蔽机制 — 通过 PushKit 唤醒可以在没有用户明确授权的情况下加载内容、同步数据和更新界面。Apple 认为这违反了节能概念,并将 PushKit 仅限制于指示入局通话。

现在每个 PushKit 通知必须立即导致通过 CallKit 显示入局通话。如果系统发现 PushKit 用于其他目的 — 例如用于后台同步或更新内容而不显示通话 — 应用程序可能在审核时被拒绝或与 PushKit 服务断开连接。Apple 还从 iOS 13 开始删除了通过 PushKit 更新后台数据的能力。

Apple 对使用 PushKit 的建议(iOS 13+uff09

  • 每个 VoIP 通知必须在接收到 push 后 5 秒内调用 reportNewIncomingCall
  • 不要将 PushKit 用于 ping、内容同步或 token 更新 — 这些有 background fetch
  • 服务器端只应在真实入局通话时发送 push,不要用于预先唤醒
  • 如果接收到 push 后没有随后的通话,用户将在 Recents 中看到未接通话 — 这会让人困惑

在 Swift 中集成 PushKit

完整的 PushKit 集成包括注册、获取 push token 以及处理入局通知。PushKit独立请求发送通知的权限 — 不需要额外调用 UNUserNotificationCenter 来为 PushKit 本身请求权限,但可能需要用于应用程序的本地通知。注册后,系统调用 pushRegistry:didUpdatePushCredentials 方法来传递 push token,该 token 必须发送到服务器。

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

从服务器发送 push 通知

服务器端通过 APNs 发送 PushKit 通知,使用push-type = voip和 apns-push-type: voip 标头。与普通 APNs 不同,VoIP-push 使用自己的证书,不需要 topic 配置。载荵应包含最少量的数据来识别通话。

json
// VoIP push 载荷示例
{
    "aps": {
        "alert": {}
    },
    "caller": "+15551234567",
    "callerName": "Alice Johnson",
    "sessionId": "abc-123-def",
    "hasVideo": false
}

PushKit 通知的诊断和调试

调试 PushKit 比标准 APNs 更困难,因为PushKit在 iOS 仿真器上不工作。诊断需要物理 iPhone 或 iPad。正确工作的第一个信号是启动时调用 pushRegistry:didUpdatePushCredentials 并出现特定格式的 push token(VoIP 为 64 个十六进制字符)。如果委托人未被调用,请检查应用程序的 entitlements。

另一个常见问题是PushKit 在更新应用程序后无法传递通知。这是因为 push token 发生了变化,但服务器继续使用旧的 token。解决方案是在应用程序启动时将新的 token 发送到服务器,并在调用 pushRegistry:didInvalidatePushTokenForType 时删除无效的 token。Apple 还建议通过普通 APNs 实现备用机制。

常见问题及解决方案

问题原因解决方案
didUpdatePushCredentials 未被调用缺少 entitlements 或类型错误在 Xcode 中检查 Capabilities → Push Notifications + VoIP
Push 延迟到来设备处于低功耗模式或信号弱PushKit 无法绕过硬件限制
重启后无通知重新安装应用后 push token 变化请求新 token 并在服务器上更新
App Store 因 PushKit 被拒PushKit 未用于通话确保每次 push 都导致 reportNewIncomingCall

常见问题

可以在不使用 CallKit 的情况下使用 PushKit 吗?

从技术上讲可以,但是毫无意义。从 iOS 13 开始,PushKit 唯一允许的应用是指示入局通话,这需要 CallKit 来显示。在不使用 CallKit 的情况下使用 PushKit 将导致应用程序在 App Store 中被拒绝。

PushKit 载荷的最大大小是多少?

PushKit 的最大载荷大小为5 KB(5120 字节)。这比普通 APNs 通知大 1 KB,可以传输更多关于通话的元数据。

如果删除带有 PushKit 的应用程序会怎么样?

Apple 在删除应用程序时自动清除 push token。服务器将收到注销通知,并应停止向该 token 发送 push。尝试向无效的 token 发送 push 将导致 APNs 错误 410。

PushKit 在 macOS 上工作吗?

PushKit 在macOS 10.14+上可用于使用 Mac Catalyst 或 AppKit 创建的 Mac 应用程序。功能与 iOS 版完全类似,包括对 VoIP 通知的支持。

如何检查 PushKit 连接是否活跃?

使用自己的分析:跟踪从服务器发送 push 到客户端调用 didReceiveIncomingPushWithPayload 之间的时间。平均时间低于 500 毫秒表示 PushKit 工作正常。

总结

  • PushKit — Apple 的高优先级 push 通知传递框架,使用永久 TCP 连接,确保延迟低于 500 毫秒。
  • PKPushRegistry 注册应用程序接收特定类型的通知 — VoIP、Complication、FileProvider 或 PushToTalk。
  • 从 iOS 13 开始,PushKit 唯一允许的应用是通过 CallKit 指示入局通话;禁止通过 PushKit 更新后台数据。
  • 与 APNs 的差异 — 专用 TCP 频道无缓冲,保证从任何状态唤醒应用程序。
  • 载荵限制为 5 KB;每个 VoIP-push 必须在 5 秒内调用 reportNewIncomingCall。
  • 诊断 PushKit 需要物理设备 — 不支持仿真器;token 必须在每次启动时更新。
  • PushKit + CallKit — VoIP 应用程序的标准组合:PushKit 传递通知,CallKit 显示系统通话屏幕。

我们将开发一款交钥匙移动应用程序

IT Sectr自2017年以来为初创企业和企业打造iOS和Android应用程序。我们将为您提供咨询并提出最佳解决方案。

讨论项目

另请阅读