iOS 13 Killing应用程序,因为它在收到PushKit VoIP回调后从未向系统发布来电

Mar*_*ina 11 voip apple-push-notifications pushkit callkit ios13

升级到iOS Beta 13之后,我注意到了一件不愉快的事情:我的应用有时会因传入的VoIP推送而崩溃。

在崩溃报告中,我看到以下内容:

iOS 13 Killing app because it never posted an incoming call to the system after receiving a PushKit VoIP callback 

Fatal Exception: NSInternalInconsistencyException
0  CoreFoundation                 0x1af21b9f0 __exceptionPreprocess
1  libobjc.A.dylib                0x1af7284fc objc_exception_throw
2  CoreFoundation                 0x1af11efec + 
 [_CFXNotificationTokenRegistration keyCallbacks]
3  Foundation                     0x1aeda1330 -[NSAssertionHandler 
 handleFailureInMethod:object:file:lineNumber:description:]
4  PushKit                        0x19caa6b54 -[PKPushRegistry 
 _terminateAppIfThereAreUnhandledVoIPPushes]
5  libdispatch.dylib              0x1afa441ec _dispatch_client_callout
6  libdispatch.dylib              0x1af9f6c6c 
_dispatch_lane_barrier_sync_invoke_and_complete
7  PushKit                        0x19caa5b74 __73-[PKPushRegistry 
 voipPayloadReceived:mustPostCall:withCompletionHandler:]_block_invoke
8  libdispatch.dylib              0x1afa43678 
 _dispatch_call_block_and_release
9  libdispatch.dylib              0x1afa441ec 
  _dispatch_client_callout

10 libdispatch.dylib              0x1af9f61f8 
_dispatch_main_queue_callback_4CF$VARIANT$mp
11 CoreFoundation                 0x1af1992a0 
CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE
12 CoreFoundation                 0x1af1942a8 __CFRunLoopRun
13 CoreFoundation                 0x1af1937ac CFRunLoopRunSpecific
14 GraphicsServices               0x1ae395180 GSEventRunModal
15 UIKitCore                      0x1b6e60244 UIApplicationMain
16 VOIPProject                    0x1009822d8 main + 25 
(AppDelegate.swift:25)
17 libdyld.dylib                  0x1af6e9e7c start
Run Code Online (Sandbox Code Playgroud)

我不明白如何解决该问题。每当收到VoIP推送消息时,我是否必须发布CallKit来电屏幕?这听起来很疯狂,因为在显示带有来电的屏幕之前,我检查通知是否有效。谁能解释我该怎么办?

pep*_*psy 19

在此线程从苹果论坛上,来自苹果的工作人员解释说有人这样:

在iOS 13.0和更高版本上,必须使用CallKit框架在收到传入IP语音呼叫时,并且在didReceiceIncomingPush()方法执行完毕之前,报告传入的IP语音呼叫,否则系统将终止您的应用程序。

反复未能报告呼叫可能会阻止您的应用接收更多来电通知。

基本上,您不能再将VoIP推送用于非VoIP消息传递,而将需要使用常规的推送通知。

这是在WWDC会议“应用程序后台执行的进展”会议期间宣布的:https://developer.apple.com/videos/play/wwdc2019/707/


我一直在寻找有关如何适应此更改的应用程序的答案,我可以收集以下内容:

语音推送

当您的应用收到这种推送时,它将需要使用CallKit报告新的来电。因此,这种推送仅适用于使用CallKit的呼叫。

建议您将通知的apns-expiration值设置为0或很小的值,这样您就不会收到推送通知,并且会被迫为已过期的呼叫显示呼叫屏幕。

推送通知

定期推送通知是另一种选择。如果您的服务器具有编写通知文本所需的所有信息,则可以发送甚至不会在后台运行应用程序的通知。如果需要在将通知内容呈现给用户之前修改通知的内容,则可以使用Notification Service应用程序扩展,并且如果需要唤醒应用程序并在后台执行某些操作,则可以发送静默推送通知。

通知服务应用程序扩展

要使用此功能,必须将通知的设置mutable-content为1。这样,扩展程序将在收到通知之前将其显示给用户,允许您在30秒的时间内更改其内容。

缺点是您的应用程序将保留在后台,仅允许您的扩展程序运行。这可能意味着您将需要在应用程序和扩展之间共享信息和代码,方法是使用用户默认值,钥匙串或共享整个数据库(如果您的应用程序没有为此做好准备,这可能不是一个简单的任务) 。

静默推送通知

要发送静默推送通知,您必须将通知的设置content-available为1并删除它的alertbadgesound。该通知将在后台唤醒您的应用,并调用您的应用代表的didReceiveRemoteNotification

该选项的缺点很烦人:

  • 您将只获得30秒的运行时间。
  • 这些通知必须apns-priority为5,这可能导致它们被分组并突发发送,甚至被限制或不发送。
  • 如果用户强行关闭应用程序,它将完全忽略所有静默通知,直到用户再次打开应用程序为止。

  • @MehulThakkar是的,iOS13上的这一更改带来了很多麻烦。我对自己的解决方案仍然不满意,但是感觉别无选择。在我正在使用的应用程序中,用户可以选择不使用callkit ...然后,我们使用自己的呼叫屏幕,并向用户显示通知,以供他打开应用程序并查看呼叫屏幕。但是,我们曾经使用voip push来进行此通知,现在我们不得不使用常规的push,这可能会延迟到达,可能是在被叫方已经放弃通话之后。 (2认同)
  • @MehulThakkar 使用 Xcode 10 (iOS 12) 构建可能暂时避免 iOS13 中的此限制。我在中国,可以看到微信仍然使用PushKit,没有CallKit(强制关闭后仍然可以在语音通话中触发,并且接听时没有闪屏)。如果这是真的,这种情况会持续多久?如果这是错误的,那么如何在没有 PushKit 的情况下达到这种效果?据我所知,强制关闭后远程静默推送通知将不起作用。 (2认同)
  • 是的,从 2020 年 4 月开始需要 Xcode 11。“使用 Xcode 11 构建”部分 https://developer.apple.com/app-store/submissions/ (2认同)