iOS 13无法在后台接收VoIP推送通知

12

我正在使用CallKit和PushKit在Swift中开发软电话。在iOS 13之前,VoIP通知正常工作。但是在iOS 13更新之后,当我的应用程序处于后台时,它无法获得VoIP推送通知。在前台,didReceiveIncomingPushWith被调用,但在后台它不会被调用。

我该如何解决这个问题?

代码

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    // Override point for customization after application launch.
    print("\(#function)")
    let voipPushResgistry = PKPushRegistry(queue: nil)
    voipPushResgistry.delegate = self
    voipPushResgistry.desiredPushTypes = [PKPushType.voIP]

    return true
}

func pushRegistry(_ registry: PKPushRegistry, didInvalidatePushTokenFor type: PKPushType) {
    print("\(#function) token invalidated")
}

func pushRegistry(_ registry: PKPushRegistry, didUpdate credentials: PKPushCredentials, for type: PKPushType) {
    let deviceToken = credentials.token.reduce("", {$0 + String(format: "%02X", $1) })
    print("\(#function) token is: \(deviceToken)")
}

func pushRegistry(_ registry: PKPushRegistry, didReceiveIncomingPushWith payload: PKPushPayload, for type: PKPushType, completion: @escaping () -> Void) {
    print("\(#function)")
    print("It worked..")
    if type == .voIP {
        print("Uygulama aktif")
    }
}
感谢。
4个回答

25
如果您使用Xcode 11(和iOS 13 SDK)构建应用程序,如果未向CallKit报告,则PushKit将不再起作用。
在iOS 13.0及更高版本中,如果您未向CallKit报告呼叫,则系统将终止您的应用程序。反复未能报告呼叫可能会导致系统停止向您的应用程序发送任何其他VoIP推送通知。如果您想发起VoIP呼叫而不使用CallKit,请使用UserNotifications框架注册推送通知,而不是PushKit。

https://developer.apple.com/documentation/pushkit/pkpushregistrydelegate/2875784-pushregistry


4
这应该是被接受的答案。苹果表示,在收到传入的 VoIP 推送后(在相同的运行循环中),需要立即调用 reportNewIncomingCall 函数到 CallKit 中。否则,应用程序将在启动时崩溃,并且它会产生一种效果,就好像传入的呼叫从未到达过一样。如果您无法在与 VoIP 推送到达时的相同运行循环中向 CallKit 报告新的传入呼叫,苹果将停止发送 VoIP 推送。 - Miki
没错,但问题有点误导人。我知道这个iOS 13的限制,但据我所知,如果你未能报告一个电话,无论它是在后台还是前台,应用程序都会崩溃。因此,这让我认为这不是正确的答案。 - Marco
这意味着现在使用Xcode 10构建将暂时避免此限制?有人可以确认吗?我已经将我的storyboard升级到Xcode 11了。CallKit在中国被禁止,我需要时间来采用UserNotifications。感谢任何帮助。 - steven
7
你知道WhatsApp如何仍在使用VoIP通知吗? - Anshul
有什么想法吗?我不知道为什么应用在后台或被杀掉时无法运行。 - famfamfam

10

@mudassirzulfiqar在Github上回答了这个问题(感谢他)。我在卸载并重新安装我的应用程序后收到了voip推送通知。现在,我将在 didReceiveIncomingPushWith 中调用 reportNewIncomingCall

我已经找出了问题,正如苹果官方论坛所述,不调用完成会导致您的应用程序在3到5次尝试后被禁止。所以我认为当应用程序在2到3次尝试中被禁止时,它将停止接收voip。

使用场景:重新安装我的应用程序并将其放入后台,didReceiveIncomingPushWith被调用。但是因为我没有在正确的时间使用完成闭包,可能下一次我不会再次收到voip。当应用程序在前台运行时,这总是正常工作的。


2
谢谢!这对我也有用。PushKit实际上有两个不同版本的“didReceiveIncomingPushWith”方法,我之前使用的是没有完成处理程序的方法,而使用带有完成处理程序的方法对我有用。再次感谢 :) - Rishabh
@Rishabh,你能分享一些关于这两个版本的更多信息以及为什么它很重要吗? - alext
@AleksandarT 请查看下面的链接:https://developer.apple.com/documentation/pushkit/pkpushregistrydelegate/1614492-pushregistry实际上,苹果公司刚刚废弃了第一个版本,现在我们需要使用带有完成块的新版本,在这里,完成块用于通知我们的进程已完成并报告调用。 - Rishabh
1
正确答案! - Andreas Pardeike
你真是救命恩人!我花了两天时间解决这个问题。 - Daniel

4

使用进行编译时,您将无法再通过VoIP通知收到新的来电并不报告新来电。

请查看此问题,我已经解释了您可以用于不应提示新来电的通知选项。


3
翻译如下:

文档中写道:

通常情况下,您需要在应用程序运行期间保持 push 注册对象一直运行。

尝试将 voipPushResgistry 声明为 AppDelegate 的属性,而不是 application(didFinishLaunchingWithOptions) 函数的变量。也许这可以帮助您。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接