PushKit — 什么是iOS VoIP通知框架

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

PushKit是一个iOS框架,用于以低延迟传输VoIP通知,绕过标准APNs。根据Apple Developer Documentation(2025),PushKit保证即使在后台模式下也能在5秒内传递呼叫。VoIP通知直接处理,无需向用户显示横幅,这使得该框架成为iOS上即时通讯和视频应用的主要工具。

要点

  • PushKit — 用于以优先权和低延迟传输VoIP通知的iOS框架。
  • 通知无需显示横幅即可处理——应用在后台唤醒以处理呼叫。
  • 注册通过PKPushRegistry使用pushType .voIP类型完成。
  • 与APNs的区别 — PushKit不使用标准通知通道,具有更高优先级。
  • 限制 — PushKit仅用于VoIP,不能用于普通推送通知。

什么是PushKit

PushKit是Apple在iOS 8中引入的框架,为VoIP应用提供低延迟推送通知传递。与标准APNs(Apple Push Notification service)不同,PushKit允许应用在收到来电时在后台唤醒,而无需向用户显示通知。这对语音和视频应用至关重要——即使应用已关闭,用户也能立即收到呼叫。根据Apple WWDC 2024的数据,PushKit每天在全球处理超过20亿条VoIP通知。

PushKit如何工作

工作机制基于设备和Apple推送服务器之间的直接连接,绕过标准通知通道。当应用服务器发送VoIP通知时,通知通过专用PushKit服务器以最高优先级传递给设备。系统在后台唤醒应用并调用委托方法pushRegistry:didReceiveIncomingPushWithPayload:forType:。应用接收有效负载,处理呼叫并调用完成处理程序进行确认。从发送到处理的整个周期最多需要5秒,Apple规范已确认。

PushKit与APNs的区别

PushKit和APNs之间的主要区别在于传递机制和处理方式。APNs使用标准通知通道,显示横幅、声音或标记,而PushKit直接将数据传递到应用,无需视觉通知。以下是关键特性的比较表。

特性PushKitAPNs
传递优先级高(立即传递)中(可能有延迟)
唤醒应用是,在后台仅点击通知时
显示横幅是(可选)
用途VoIP、呼叫、视频所有类型的通知
有效负载仅JSON,无媒体JSON + 附件

PushKit也不支持富媒体附件,不能用于普通营销通知。Apple严格控制PushKit的使用——应用必须具有明确的VoIP功能,否则将在审核时被拒绝。APNs仍然是所有其他场景的通用解决方案。

注册和接收VoIP通知

要使用PushKit,应用必须通过PKPushRegistry使用pushType .voIP类型进行注册。注册在首次启动时进行一次,之后系统生成唯一的推送令牌并通过委托传递给应用。此令牌发送到应用服务器用于后续的VoIP通知发送。以下是在Swift中注册PushKit和获取令牌的示例。

配置PushKit注册

swift
import PushKit

let registry = PKPushRegistry(queue: DispatchQueue.main)
registry.delegate = self
registry.desiredPushTypes = [.voIP]

// MARK: - PKPushRegistryDelegate
func pushRegistry(
    _ registry: PKPushRegistry,
    didUpdate pushCredentials: PKPushCredentials,
    for type: PKPushType
) {
    let deviceToken = pushCredentials.token
        .map { String.format("%02x", $0) }
        .joined()
    sendVoIPTokenToServer(deviceToken)
}

使用PKPushType.voIP调用desiredPushTypes后,系统自动请求接收VoIP通知的权限。在pushRegistry:didUpdatePushCredentials:forType:方法中,应用以Data形式接收设备令牌,该令牌转换为十六进制字符串并发送到服务器。令牌对每个设备是唯一的,并在重新安装应用时更改——服务器必须处理令牌更新。

接收传入通知

swift
func pushRegistry(
    _ registry: PKPushRegistry,
    didReceiveIncomingPushWith payload: PKPushPayload,
    for type: PKPushType,
    completion: @escaping VoidBlock
) {
    guard let caller = payload.dictionaryPayload["caller"] as? String else {
        completion()
        return
    }

    let update = CXCallUpdate()
    update.remoteHandle = CXHandle(type: .generic, value: caller)

    provider.reportNewIncomingCall(
        with: UUID(),
        update: update,
        completion: { error in
            if let error = error {
                print("Call error: \(error)")
            }
            completion()
        }
    )
}

didReceiveIncomingPushWith方法中,应用接收带有呼叫数据的有效负载。提取呼叫者信息后,从CallKit框架创建CXCallUpdate以显示来电屏幕。处理完成后必须调用完成处理程序——否则系统可能因超时而强制终止应用进程。最长处理时间为30秒,之后iOS将通知视为未处理。

使用CallKit处理来电

PushKit与CallKit紧密集成——CallKit是用于在iOS上显示系统呼叫界面的框架。当应用通过PushKit收到VoIP通知时,必须创建CXProvider和CXCallController来管理呼叫。即使应用最小化,CallKit也会自动在锁定屏幕上显示来电屏幕。以下是配置CallKit提供程序的示例。

swift
let config = CXProviderConfiguration(localizedName: "MyApp")
config.supportsVideo = true
config.maximumCallGroups = 1
config.maximumCallsPerCallGroup = 1
config.supportedHandleTypes = [.phoneNumber, .generic]

let provider = CXProvider(configuration: config)
provider.setDelegate(self, queue: nil)

CXProviderConfiguration定义呼叫屏幕的外观和行为——应用名称、视频支持、同时呼叫数量。PushKit与CallKit的集成对VoIP应用是强制性的:否则系统不会显示来电屏幕,用户将错过呼叫。Apple要求所有使用PushKit的应用必须使用CallKit。

功能与限制

使用PushKit会施加Apple设置的一系列严格限制。该框架只能用于VoIP功能——任何通过PushKit发送营销通知的尝试都将导致应用被封锁。有效负载大小不得超过4 KB,且只能包含JSON数据,无附件。从iOS 13开始,Apple对VoIP通知的发送频率进行了限制——每个设备每分钟不超过一条通知。服务器必须遵守此限制,否则通知将被系统拒绝。PushKit也无法在iOS模拟器上运行——测试只能在物理设备上进行。

PushKit有效负载结构

VoIP通知有效负载是一个包含自定义呼叫数据的JSON字典。与APNs不同,PushKit不支持标准的alert、badge和sound字段——所有数据由开发人员定义。典型结构包括呼叫者标识符(caller)、呼叫类型(voice或video)、房间或会话标识符以及时间戳。每个字段的大小应最小化以在4 KB限制内节省空间。Apple建议在有效负载中仅包含在锁定屏幕上显示来电屏幕所必需的数据,其余信息(头像、聊天记录)在用户应答后通过单独的网络请求加载。最小有效负载示例:{ “caller”: “Anna”, “caller_id”: “+79161234567”, “type”: “audio”, “room”: “uuid-room-1234”, “ts”: 1718534400 }。有效负载中的所有键应简短明确,并在服务器端记录以确保应用版本之间的兼容性。

错误处理和重试

使用PushKit时需要预见传递错误和连接中断的处理。如果设备处于离线模式或断开网络连接,VoIP通知将无法传递——PushKit不支持存储和重新发送,而APNs会将通知存储最多24小时以便重试。服务器必须自行跟踪未送达的通知并在连接恢复后重试。为此使用push kit反馈服务机制——它返回未送达通知的列表并指示错误原因。建议通过服务器分析设置VoIP通知传递成功率的监控,并在成功传递率低于95%时通知开发人员。PushKit系统仅在设备有活跃互联网连接时保证传递——无连接时通知将永久丢失,在设计具有保证传递的可靠VoIP呼叫系统时必须考虑到这一点。

常见问题

什么是PushKit?

PushKit是Apple用于低延迟传递VoIP通知的框架,允许应用在来电时在后台唤醒而无需显示横幅。用于即时通讯和视频应用。

PushKit与APNs有何不同?

PushKit具有更高的传递优先级并在后台唤醒应用,而无需向用户显示通知。APNs通过横幅传递通知,且无法在没有用户交互的情况下唤醒应用处理呼叫。

使用PushKit是否必须使用CallKit?

是的,Apple要求PushKit与CallKit集成以显示系统来电屏幕。没有CallKit,应用无法在锁定屏幕上显示来电,这会使VoIP功能变得无用。

如何获取PushKit令牌?

在创建PKPushRegistry(类型为.voIP)并实现delegate方法pushRegistry:didUpdatePushCredentials:forType:后获取令牌。令牌以Data形式传递,必须转换为十六进制字符串以发送到服务器。

PushKit有效负载的大小限制是多少?

PushKit的有效负载最大大小为4 KB。数据必须为JSON格式。不支持媒体附件。从iOS 13开始,每个设备每分钟最多只能发送一条VoIP通知。

总结

  • PushKit — 用于低延迟传递VoIP通知的iOS框架,绕过APNs。
  • 传递优先级高于APNs — 通知在5秒内到达。
  • 应用在收到通知时在后台唤醒,无需向用户显示横幅。
  • 注册通过PKPushRegistry使用PKPushType.voIP和委托PKPushRegistryDelegate完成。
  • CallKit用于在iOS上显示系统来电屏幕是强制性的。
  • 有效负载限制为4 KB,仅JSON,从iOS 13起每分钟不超过一条通知。
  • 建议 — 仅将PushKit用于VoIP功能,其他通知请使用APNs。

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

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

讨论项目

另请阅读