2020年4月30日之后,苹果不接受Xcode 10的构建。它要求上传iOS 13 SDK的构建。我也试过同样的方法,现在我遇到了以下错误导致的崩溃。
[PKPushRegistry _terminateAppIfThereAreUnhandledVoIPPushes]
我的应用程序是一个社交媒体应用程序,它包含来自Twilio的音频/视频通话、聊天、提要发布和许多其他功能。它包含用于多种用途的推送通知。现在,该应用程序要么没有收到推送,要么在收到推送时崩溃(处于后台或终止状态(。当我搜索时,我发现如果我的应用程序没有显示Callkit来电屏幕,或者应用程序没有处理VOIP通知,我不允许使用PushKit。我的应用程序包含两种通知,即VOIP和非VOIP。因此,这意味着我必须同时使用PushKit和APNS这两种通知。
你能帮我如何在一个应用程序中实现这两个通知吗?我只能通过PushKit实现目标吗?我需要在应用程序中进行哪些更改才能实现?还有其他扭转局面的解决方案吗?
正在查找您的建议。
简单的答案是:
你需要在你的应用中实现两个推送
您只能将PushKit用于代表应用程序新来电的推送,并且当您通过PushKit收到推送时,必须始终在CallKit屏幕上显示新来电。
对于您可能想要发送的其他通知,您必须使用定期推送。
如何实现?
首先,你的应用程序需要向苹果注册两次推送,并获得两个推送代币。
要注册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将只显示通知,不会唤醒您的应用。
通知服务扩展(令牌:Regular(:当您需要一些仅在客户端可用的信息时,可以使用此推送。要使用它,只需将标志
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
}
}
可变内容通知将由您的通知服务扩展处理。
静默推送将由您的AppDelegate:处理
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
print("Silent push received")
}