跳转到主要内容
VoIP 推送通知让您的应用即使在后台或已终止时也能接收来电提醒。Apple 对 VoIP 推送的处理方式与标准推送通知不同——它们使用独立的证书类型、独立的令牌(通过 PushKit),以及不同的传递规则。 OneSignal 支持发送 VoIP 推送,但 OneSignal SDK 处理 VoIP 令牌注册。您需要负责:
  • 在应用中使用 Apple PushKit 注册 VoIP 令牌
  • 创建一个使用 VoIP Services 证书的专用 OneSignal 应用
  • 通过 OneSignal REST API 注册令牌并发送推送

平台差异

平台是否支持 VoIP 推送工作原理
iOSYes使用 Apple PushKit 和 VoIP APNs 证书
AndroidNo使用纯数据推送模拟通话样式行为
如果您正在构建跨平台通话应用,则需要针对不同平台使用不同的方法。

iOS:发送 VoIP 推送通知

在 iOS 上,VoIP 通知使用 Apple PushKit,并遵循与标准推送通知不同的特殊传递规则。由于 Apple 对 VoIP 推送的处理方式不同,OneSignal 需要为 VoIP 使用单独的应用配置。
开始之前 — 以下是最常见的 VoIP 设置错误:
  1. 未为 VoIP 创建独立的 OneSignal 应用。 Apple 要求 VoIP 使用不同的证书类型,因此 OneSignal 需要一个专用应用来发送 VoIP 推送。您现有的推送应用不能同时用于两者。
  2. 上传了错误的证书。 您需要 VoIP Services 证书(.p12),而不是标准的 APNs 推送证书。使用错误的证书会导致静默传递失败。
  3. 在沙盒环境中忘记填写 test_type 使用开发构建进行测试时,注册令牌时必须包含 "test_type": 1。不包含此字段时,API 调用会成功,但推送始终无法送达。
1

使用 PushKit 注册 VoIP 令牌

使用 Apple 的 PushKit 框架注册 VoIP 通知并获取 VoIP 令牌。
  • 在您的应用中实现 PushKit
  • 在 Apple 轮换时存储并刷新 VoIP 令牌
  • 严格遵守 Apple 的 VoIP 策略
import PushKit

class AppDelegate: NSObject, PKPushRegistryDelegate {
    func registerForVoIPPushes() {
        let registry = PKPushRegistry(queue: .main)
        registry.delegate = self
        registry.desiredPushTypes = [.voIP]
    }

    func pushRegistry(_ registry: PKPushRegistry, didUpdatePushCredentials credentials: PKPushCredentials, for type: PKPushType) {
        let token = credentials.token.map { String(format: "%02x", $0) }.joined()
        // Pass this token to OneSignal — see Step 4
    }
}
这是标准的 Apple PushKit 代码。OneSignal 不提供 PushKit SDK——您需要自行注册令牌,然后在第 4 步将其传递给 OneSignal。
Apple 资源:
2

为 VoIP 创建独立的 OneSignal 应用

Apple VoIP 推送需要与标准推送通知不同的证书类型。单个 OneSignal 应用只能使用一种证书类型,因此您必须创建两个独立的 OneSignal 应用
  • 主推送应用:使用 APNs 证书处理标准推送通知
  • VoIP 推送应用:使用 VoIP Services 证书专门处理 VoIP 通知
两个应用都必须使用相同的 iOS Bundle ID,并与同一原生 iOS 应用关联。您无需初始化 OneSignal SDK 两次——VoIP 应用仅在服务端通过 API 发送 VoIP 推送时使用。
Bundle ID(例如 com.yourcompany.appname)可在 Xcode 中您的 target 的 General 选项卡下找到。
3

上传 VoIP Services 证书

在您的 VoIP OneSignal 应用中,上传 VoIP Services 证书(.p12)。这与您用于常规通知的标准 APNs 推送证书是不同的证书类型。创建步骤:
  1. 前往 Apple Developer Portal
  2. 选择 VoIP Services Certificate
  3. 按照提示生成并下载证书
  4. 在”钥匙串访问”中打开并将其导出为 .p12 文件
  5. .p12 文件上传至您的 VoIP OneSignal 应用的 iOS 设置中
不要将标准 APNs 推送证书上传到 VoIP 应用。如果使用了错误的证书类型,API 会接受您的推送请求,但 Apple 会拒绝它,通知将永远无法送达。
macOS 钥匙串访问中显示的 VoIP Services 证书
在 OneSignal 仪表板中上传的 VoIP Services 证书
4

向 OneSignal 注册 VoIP 令牌

使用 Create User API 将 VoIP 令牌注册到您的 VoIP OneSignal 应用。
沙盒/开发构建需要填写 "test_type": 1 如果省略此字段,API 调用会成功且不返回任何错误,但 Apple 会将该令牌视为生产令牌并静默拒绝所有发送至该令牌的推送。
curl --request POST \
     --url https://api.onesignal.com/apps/YOUR_VOIP_APP_ID/users \
     --header 'accept: application/json' \
     --header 'content-type: application/json' \
     --data '
{
  "subscriptions": [
    {
      "type": "iOSPush",
      "token": "YOUR_VOIP_TOKEN",
      "test_type": 1
    }
  ]
}
'
有效的 VoIP 令牌是 64 个字符的小写十六进制字符串(例如 a1b2c3d4e5f6...)。PushKit 在 iOS 模拟器上无法使用——您必须使用真实设备才能获取有效令牌。
如需稍后更新令牌,请使用 Update Subscription API。
5

发送 VoIP 通知

使用 Create Notification API 并包含以下参数:
  • "apns_push_type_override": "voip" — 告知 Apple 这是 VoIP 推送
  • app_id — 您的 VoIP 应用 ID
  • include_subscription_ids — 您注册的 VoIP 订阅 ID
  • contentscontent_available 二选一,必须填写
curl --include \
     --request POST \
     --header "Content-Type: application/json; charset=utf-8" \
     --header "Authorization: key YOUR_REST_API_KEY" \
     --data-binary '{
  "app_id": "YOUR_VOIP_APP_ID",
  "content_available": true,
  "data": {
    "your_custom_data": "your_custom_value"
  },
  "apns_push_type_override": "voip",
  "include_subscription_ids": ["YOUR_VOIP_SUBSCRIPTION_ID"]
}' \
https://api.onesignal.com/notifications
6

验证您的 VoIP 设置

如果满足以下条件,则说明您的 iOS VoIP 集成运行正常:
  1. VoIP 令牌在您的 VoIP 应用中显示为 iOS 推送订阅
  2. VoIP 推送触发了应用中的 pushRegistry(_:didReceiveIncomingPushWith:for:completion:)
  3. 即使应用已终止或在后台运行,也能被唤醒

Android:模拟 VoIP 样式行为

Android 不支持 VoIP 推送通知,没有与 Apple PushKit 等效的功能。 Android 通话应用使用以下方式模拟 VoIP 行为:
  • 纯数据推送通知
  • 前台服务
  • 自定义通话样式 UI
您可以将 OneSignal 的常规 Android 推送支持与原生 Android API 结合使用来实现此功能。 推荐方法:
  • 发送纯数据通知
  • 在您的应用中处理它们以:
    • 启动前台服务
    • 启动通话 UI 活动
    • 显示自定义来电通知
如果您想拦截并完全控制通知呈现,请使用 Android 的通知服务扩展 有用的资源:
Android 设置并非 OneSignal 特定的。OneSignal 仅传递推送负载;您的应用负责处理通话行为。

常见问题

确认送达功能是否适用于 VoIP?

不适用。VoIP 推送不会跟踪确认送达。确认送达依赖于通知服务扩展,而通知服务扩展不会为 VoIP 通知触发。 请通过原生 iOS PushKit 事件来跟踪接收情况:
pushRegistry(_:didReceiveIncomingPushWith:for:completion:)
此事件是主应用 target 的一部分,不需要单独的扩展。详情请参阅 Apple 的 VoIP 文档

能否从 OneSignal 仪表板发送 VoIP 通知?

不能。VoIP 通知必须通过 Create Notification API 并携带 "apns_push_type_override": "voip" 参数来发送。仪表板不支持此参数。

为什么我的 VoIP 推送静默失败?

VoIP 推送可能在 OneSignal API 不返回任何错误的情况下失败。请逐一检查以下清单:
  1. 您使用的是沙盒/开发构建吗? 通过 Create User API 注册令牌时,必须包含 "test_type": 1。不包含此字段时,令牌会被注册为生产令牌,Apple 会拒绝推送并静默失败。
  2. 您上传了正确的证书吗? VoIP OneSignal 应用必须使用 VoIP Services 证书(.p12),而非标准 APNs 推送证书。两者在”钥匙串访问”中看起来相似——请确认证书名称以”VoIP Services”开头。
  3. 您是否向正确的 OneSignal 应用发送? 发送请求中的 app_id 必须是您的 VoIP 应用,而非主推送应用。REST API Key 也必须来自 VoIP 应用。
  4. VoIP 令牌是否有效? 重新安装应用或恢复设备后令牌会过期。请确认令牌是 64 个字符的小写十六进制字符串,且是近期注册的。
  5. 您的应用是否调用了 reportNewIncomingVoIPPushPayload 从 iOS 13 开始,Apple 会终止收到 VoIP 推送但未向 CallKit 报告通话的应用。这是 Apple 的要求,而非 OneSignal 的限制。

相关页面

创建消息 API

使用 REST API 以编程方式发送推送通知。

确认送达

在支持的平台上跟踪推送通知的送达确认。

服务扩展

使用通知服务扩展自定义通知处理。

Create User API

通过 OneSignal API 注册用户和订阅。