IOS 13 条 VOIP 推送通知在应用被 KILLED 时未收到

IOS 13 VOIP Push Notifications not received when app is KILLED

我们有一个使用 WebRTC 进行视频聊天的 Cordova 应用程序。
我们正在使用这个插件来实现 VOIP 推送通知 https://github.com/mattkhaw/cordova-plugin-callkit.
除此之外,我们还使用 AWS SNS 为我们处理 VOIP 推送。
流程如何运作?

IOS Device Calee (User A)
1. When device opens the app, it registers on Apple servers and 
receives a VOIP Device Token
2. We call Amazon SNS to save the token and get the endpointARN for that token
3. We save the token in the database along with the user ID and endpointARN 
from AWS

Caller Side (User B)
1. User B wants to call User A
2. User B clicks the call button
3. A request it send to the server, which checks if a token exists for User A 
in the database.
4. If it exists, we call AWS SNS endpointARN so it will 
send a VOIP push to User A

当应用程序打开或应用程序处于后台时,所有这些都工作正常。
当应用程序被杀死(终止)时出现问题。
当应用程序被终止时,应用程序崩溃,这是我们收到的日志 https://gist.github.com/AleksandarTokarev/74068feadd728a4bd1c672a024482af4
我对日志细节做了一些研究,似乎原因写在
https://developer.apple.com/forums/thread/124517.

The exception code "0xbaadca11" indicates that your app was killled for failing to report a CallKit 
call in response to a PushKit notificaiton.  That should have been clear in the crash log,
but this particular requirement is implemented through multiple code paths and it looks like this 
one isn't as clear as the others.  For more details on the new requirement, take a look at:
https://developer.apple.com/videos/play/wwdc2019/707/

知道为什么会这样吗?当应用程序处于 运行 或后台时,该插件可以正常工作。
我正在使用以下负载调用 AWS SNS

let voip_protocol_value = `{"aps" : { "alert": "New Incoming Call" },
 "data" : { "Caller": { "Username" : "${caller}", "ConnectionId": "${Random.id()}"}}}`
                let payload = {}
                payload[`APNS_VOIP`] = voip_protocol_value
                let params = {
                    'Message': JSON.stringify(payload),
                    'MessageAttributes': {
                        'AWS.SNS.MOBILE.APNS.PRIORITY': {
                            'DataType': 'String',
                            'StringValue': '10'
                        },
                        'AWS.SNS.MOBILE.APNS.PUSH_TYPE': {
                            'DataType': 'String',
                            'StringValue': 'voip'
                        },
                    },
                    'MessageStructure': 'json',
                    'TargetArn': user.endpointArn
                }

我通过以下方式修改插件设法解决了这个问题:
https://github.com/luisbouca/cordova-plugin-callkit/compare/master...AleksandarTokarev:master.

当应用程序被杀死(终止)时,似乎没有调用 init() 函数,所以我的一个朋友帮我做了一些小的重构,并将 init() 函数代码放在插件初始化中。

这意味着 Pushkit 没有被初始化(因为它在 init() 方法中)。

init() 方法仍然存在,但在 Javascript 中初始化时会调用它。

这可能与我们的 Meteor Cordova 应用程序以及应用程序本身的初始化方式有关。

现在一切正常。