swift iOS 13 Xcode 11:PKPushKit和APNS在一个应用程序中

bvhaajcl  于 2023-05-16  发布在  Swift
关注(0)|答案(1)|浏览(136)

在2020年4月30日之后,Apple将不再接受Xcode 10的构建版本。它要求上传iOS 13 SDK的构建版本。我尝试了同样的,现在我得到崩溃,与以下错误。

[PKPushRegistry _terminateAppIfThereAreUnhandledVoIPPushes]

我的应用程序是一个社交媒体应用程序,其中包含来自Twilio的音频/视频通话,聊天,feeds post和许多其他功能。它包含用于多种目的的推送通知。现在,应用程序要么不接收推送,要么在接收推送时崩溃(处于后台或已终止状态)。当我搜索时,我发现我不允许使用PushKit,如果我的应用程序不呈现Callkit来电屏幕或应用程序不处理VOIP通知。我的应用程序包含两种通知,即VOIP和非VOIP。所以,这意味着我必须使用两个通知,即PushKit和APNS。
请问你能帮助我如何在一个应用程序中实现这两个通知?我只能通过PushKit实现我的目标吗?我需要在我的应用中进行哪些更改才能实施?还有其他的解决办法吗?
寻求您的建议。

mspsb9vt

mspsb9vt1#

简短的回答是:
您需要在应用中实现这两种推送
您只能将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):仅用于通知来电。无例外。
  • 常规(令牌:常规):当您的服务器端提供了编写通知消息所需的所有信息时,使用它。您的应用在收到此推送时不会运行任何代码,iOS只会呈现通知,不会唤醒您的应用
  • Notification Service Extension(令牌:常规):当您需要一些仅在客户端可用的信息时,可以使用此推送。要使用它,只需将标志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")
}

相关问题