PAYATHON 2026

使用 Apple Push Notification Service (APNS) 是否免费?

支付小周

结论

APNs 不按通知数量、设备数量或订阅用户数量收费。即使要向数百万台 Apple 设备发送推送通知,也不需要按发送条数向 Apple 支付 APNs 使用费。

相关费用分为两类:

  • APNs 服务费:不按调用量、通知量或设备量计费。
  • Apple Developer Program 会员费:发布正式 iOS App 通常需要加入 Apple Developer Program。会员资格可能收费,但这笔费用与 APNs 流量无关。具体金额请查看 Apple Developer Program 官方页面。

运营商仍需承担服务器、带宽、消息队列、日志存储、监控和日常运维等成本。

APNs 是否限制通知数量或订阅用户数量

Apple 没有公布统一的“订阅用户数上限”或“每日通知发送上限”。因此,即使持有数百万个设备令牌,也不需要购买更高级别的 APNs 套餐。

不过,没有公开的固定配额,并不意味着发送不受任何限制。APNs 会根据连接状态、发送频率、设备状态和通知类型进行流量控制。发送端可能收到以下响应:

  • 429 Too Many Requests:请求过于频繁,需要降低发送速率后重试。
  • 410 Unregistered:设备令牌已经失效,应停止向该令牌发送通知。
  • 400 BadDeviceToken:设备令牌无效,或与当前环境、应用不匹配。
  • 403 InvalidProviderToken:认证令牌无效或已经过期。
  • 503 ServiceUnavailable:APNs 暂时不可用,应采用退避策略重试。

APNs 也不是广播接口。向一百万台设备发送同一条消息时,通常仍要针对一百万个 device token 分别提交请求,但可以复用 HTTP/2 连接并发发送。

推荐的实现方式

大规模推送系统可以采用以下流程:

  1. App 向 APNs 注册并取得 device token。
  2. App 将 device token、用户标识、应用环境和通知偏好提交给运营商服务器。
  3. 服务端维护有效令牌,并及时删除 APNs 返回 410 的令牌。
  4. 业务系统把推送任务写入消息队列。
  5. 推送工作节点复用持久的 HTTP/2 连接,逐个令牌向 APNs 发送请求。
  6. 服务端根据 HTTP 状态码判断请求是否成功,以及是否需要删除令牌、延迟重试或触发告警。
  7. 对 429、500、503 等临时错误采用指数退避,并加入随机抖动,避免大量请求同时重试。

不要为每条通知重新建立 TLS 连接。面对数百万级发送任务,应使用连接池、限速器、队列分片和失败重试机制。

APNs 请求示例

下面的示例使用 Token-based authentication 向单个设备发送通知。PROVIDER_JWT 必须由服务端使用 APNs signing key 生成,不能写死在客户端或提交到公开仓库。

curl --http2 \
  --header "authorization: bearer ${PROVIDER_JWT}" \
  --header "apns-topic: com.example.operatorapp" \
  --header "apns-push-type: alert" \
  --header "apns-priority: 10" \
  --data '{
    "aps": {
      "alert": {
        "title": "服务通知",
        "body": "您的业务办理已完成。"
      },
      "sound": "default"
    }
  }' \
  "https://api.push.apple.com/3/device/${DEVICE_TOKEN}"

开发环境使用以下地址:

https://api.sandbox.push.apple.com/3/device/{device-token}

生产环境使用:

https://api.push.apple.com/3/device/{device-token}

APNs 成功接收请求时通常返回 HTTP 200。这只表示 APNs 接受了请求,不代表用户已经看到或点击通知。

大规模发送时的注意事项

不要把 APNs 当成送达证明

设备可能处于离线状态,也可能关闭了通知权限、卸载了 App,或受到系统通知策略影响。即使 APNs 接受了请求,也不能保证通知一定会显示给用户。重要业务不能只依靠普通推送确认送达。

合并可被覆盖的状态更新

未读数量、余额状态或进度变化等通知可以使用 apns-collapse-id 合并过时消息,避免同一设备积压大量已经没有意义的通知。

正确设置通知优先级

即时提醒可以使用适合 alert notification 的优先级。后台刷新和非紧急状态同步不应全部使用最高优先级,否则更容易受到系统调度和流量控制的影响。

控制重试范围

只有临时错误适合重试。遇到以下错误时,通常不应原样重复发送:

  • BadDeviceToken
  • DeviceTokenNotForTopic
  • Unregistered
  • PayloadEmpty
  • PayloadTooLarge

对于 429、500、503 等错误,可以采用退避策略重试,但需要设置最大重试次数和任务有效期。

注意 payload 大小

普通 APNs 通知对 payload 大小有限制,目前常见上限为 4 KB。通知中不应包含完整业务数据,只需携带展示信息和必要的业务标识,再由 App 从业务服务器获取详情。不同推送类型的限制可能不同,具体要求请查看 Sending notification requests to APNs 的最新说明。

费用方面的最终判断

运营商向数百万用户发送 APNs 通知,不需要向 Apple 支付按条、按用户或按流量计算的 APNs 费用。相关成本主要来自 Apple Developer Program 会员资格,以及运营商自行建设和维护的大规模推送基础设施。

APNs 的认证方式、请求格式和错误处理规则可参考 Apple Push Notification service 官方文档。Apple 可能调整会员费用、接口要求和流量控制策略,正式上线前应重新核对官方说明。“免费”只表示 APNs 不按使用量收费,并不表示它没有技术限制或服务端成本。

备注:内容仅供参考。