简短的回答是:
你需要在你的应用中实现这两个推送
您只能将 PushKit 用于代表应用程序新来电的推送,并且当您通过 PushKit 收到推送时,您必须始终在 CallKit 屏幕上显示新来电。
对于您可能想要发送的其他通知,您必须使用常规推送。
如何实现?
首先,您的应用需要向 Apple 注册两个推送并获取两个推送令牌。
要注册 VoIP,您将使用 PushKit:
class PushService {
private var voipPushRegistry: PKPushRegistry?
func registerForVoipPushes() {
voipPushRegistry = PKPushRegistry(queue: DispatchQueue.main)
voipPushRegistry!.delegate = self
voipPushRegistry!.desiredPushTypes = Set([PKPushType.voIP])
}
}
使用 PKPushRegistryDelegate,您可以获得 VoIP 令牌:
extension PushService: PKPushRegistryDelegate {
func pushRegistry(_ registry: PKPushRegistry, didUpdate pushCredentials: PKPushCredentials, for type: PKPushType) {
print("VoIP token: \(pushCredentials.token)")
}
}
注册常规推送:
let center = UNUserNotificationCenter.current()
let options: UNAuthorizationOptions = [.alert, .badge, .sound];
center.requestAuthorization(options: options) {
(granted, error) in
guard granted else {
return
}
DispatchQueue.main.async {
UIApplication.shared.registerForRemoteNotifications()
}
}
您将在 AppDelegate 中获得常规推送令牌:
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
print("Regular pushes token: \(deviceToken)")
}
现在您拥有两个令牌,您将把它们都发送到您的服务器。您必须重构服务器端以接受这两个令牌,并为您发送给用户的每种推送类型选择正确的一个。
您可以发送 4 种不同类型的推送:
VoIP(令牌:VoIP):仅用于通知来电。 没有例外。
Regular(令牌:Regular):当您需要编写通知消息的所有信息在您的服务器端都可用时使用它。您的应用在收到此推送时不会运行任何代码,iOS 只会显示通知,不会唤醒您的应用。
通知服务扩展(令牌:常规):当您需要一些仅在客户端可用的信息时,您可以使用此推送。要使用它,只需将标志 mutable-content: 1 添加到您的推送(在您的服务器端),并在您的应用程序中实现通知服务应用程序扩展。当 iOS 收到带有此标志的推送时,它会唤醒您的应用程序扩展并让您在那里运行一些代码。它不会唤醒您的应用程序,但您可以使用应用程序组或钥匙串在您的应用程序及其扩展程序之间共享信息。 此通知将始终显示警告横幅。
静音(令牌:常规):此推送将在后台唤醒您的应用程序,让您运行一些来,如果您不想显示通知横幅,则可以不显示。这意味着您可以使用此推送来运行一些代码,而用户甚至不会注意到。要使用它,请将标志 content-available: 1 添加到您的推送中。但请注意:此推送的优先级非常低。 静默推送可能会被延迟甚至完全忽略。
如何处理应用中的推送?
VoIP 推送将由您的 PKPushRegistryDelegate 实现处理。
extension PushService: PKPushRegistryDelegate {
[...]
func pushRegistry(_ registry: PKPushRegistry, didReceiveIncomingPushWith payload: PKPushPayload, for type: PKPushType) {
print("VoIP push received")
//TODO: report a new incoming call through CallKit
}
}
可变内容通知将由您的Notification Service Extension 处理。
静默推送将由您的 AppDelegate 处理:
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
print("Silent push received")
}