Ios 原因:';关闭应用程序,因为它在收到PushKit VoIP推送回调后从未向系统发送传入呼叫;
我正在寻找解决办法,但还没有找到任何办法。我的应用程序只接收VoIP推送,在iOS 13之后,当应用程序处于后台模式时,我无法再接收推送。我看了看其他问题,但我无法用提出的解决方案解决我的问题。 有人能帮我吗 在iOS 13.0及更高版本上,必须在收到IP语音呼叫时以及在didReceiceIncomingPush()方法完成执行之前,使用CallKit框架报告传入的IP语音呼叫,否则系统将终止您的应用程序 重复报告呼叫失败可能会阻止您的应用程序接收更多来电通知 基本上,您不能再将VoIP推送用于非VoIP消息传递,并且需要对这些消息使用常规推送通知 我读过这个公告,但在我的应用程序中,对于特定类型的推送VoIP,我不能使用函数Ios 原因:';关闭应用程序,因为它在收到PushKit VoIP推送回调后从未向系统发送传入呼叫;,ios,swift,voip,callkit,pushkit,Ios,Swift,Voip,Callkit,Pushkit,我正在寻找解决办法,但还没有找到任何办法。我的应用程序只接收VoIP推送,在iOS 13之后,当应用程序处于后台模式时,我无法再接收推送。我看了看其他问题,但我无法用提出的解决方案解决我的问题。 有人能帮我吗 在iOS 13.0及更高版本上,必须在收到IP语音呼叫时以及在didReceiceIncomingPush()方法完成执行之前,使用CallKit框架报告传入的IP语音呼叫,否则系统将终止您的应用程序 重复报告呼叫失败可能会阻止您的应用程序接收更多来电通知 基本上,您不能再将VoIP推送用
reportNewIncomingCall()
,因为它需要一些参数,如:uuid、handle、hasVideo ecc。
而且这些参数不存在于有效负载中。由于iOS 13,您只能使用VoIP推送来报告传入呼叫。对于不是传入呼叫的推送,您必须使用其他替代方法(在此处查看) 重复报告呼叫失败可能会阻止您的应用程序接收更多来电通知 从我的测试来看,它似乎在只报告了2到3次失败后就阻止了所有的VoIP推送,并且它会被阻止大约24小时 因为它需要参数,比如:uuid、handle、hasVideo ecc。这些参数不存在于有效载荷中 如果您收到一个新来电的VoIP推送,但仍然没有上面列出的所需信息,您可以使用“虚拟”值初始化呼叫,然后更新它们。例如,将remoteHandle设置为
CXHandle(type:.generic,value:“Connecting…”)
,然后使用正确的值更新它:
cxCallUpdate.remoteHandle = CXHandle(type: .emailAddress, value: "email@mail.com")
cxProvider.reportCall(with: callUid, updated: cxCallUpdate)
这不是有效负载问题。您可以创建自己的有效负载。您只需在此回调中调用下面的函数
func pushRegistry(registry:PKPushRegistry,didReceiveIncomingPushWith payload:PKPushPayload,for type:PKPushType,completion:@escaping()->Void)
否则,苹果将暂时阻止推送通知
provider.reportNewIncomingCall(with: uuid, update: update) { error in
completion() }
如果您将传入调用实现为另一个函数,并按如下方式调用它。这行不通
func pushRegistry(_ registry: PKPushRegistry, didReceiveIncomingPushWith payload: PKPushPayload, for type: PKPushType, completion: @escaping () -> Void) {
yourIncomingCallFunction()
}
相反,请尝试以下操作:
func pushRegistry(_ registry: PKPushRegistry, didReceiveIncomingPushWith payload: PKPushPayload, for type: PKPushType, completion: @escaping () -> Void) {
print("didReceiveIncomingPushWith payload")
if let callerID = payload.dictionaryPayload["callerID"] as? String,
let hasVideo = payload.dictionaryPayload["hasVideo"] as? Bool{
let update = CXCallUpdate()
update.remoteHandle = CXHandle(type: .generic, value: callerID)
update.hasVideo = hasVideo
let bgTaskID = UIApplication.shared.beginBackgroundTask(expirationHandler: nil)
self.provider?.reportNewIncomingCall(with: UUID(), update: update, completion: { (_) in
completion()
})
UIApplication.shared.endBackgroundTask(bgTaskID)
}
completion()
}
这已经在pushRegistry:didReceiveIncomingPushWith payload with completion handler
函数中实现了调用提供者发布调用请求。这对我有用
使用终端命令尝试VOIP请求:
curl -v -d '{"callerID": "test@test.com", "uuid":"YourUDIDorEmptyField", "hasVideo": false}' --http2 --cert yourvoipcertificatepemfile_Here.pem:pemfilePassword_Here https://api.development.push.apple.com/3/device/yourDeviceTokenID_generated_with_update_push_credentials_with_token_Here
替换:
test@test.com
以及CXHandle.HandleType上的相关详细信息
如果是您的呼叫者姓名(.generic
)或电子邮件(.emailAddress
)或电话号码(.phoneNumber
)
YourUDIDorEmptyField
和您的UUID
或者当reportNewIncomingCall(使用:UUID(),update:callUpdate)
在代码本身中初始化UUID()
时,您可以将其保持为空“hasVideo”:false
这里false是一个布尔值(true/false)
,显然它处理传入呼叫屏幕上的音频/视频
呼叫状态,您可以通过实现它来使用它来准确识别呼叫类型yourvoipcertificatepemfile\此处
是您从voip证书导出的.pem
文件的名称(voipcertificate.cer
不是直接生成的,而是从开发人员帐户生成并安装到您的机器上之后。然后在keychain->mycertificates
中将其导出为.pem
带有密码的文件(pemfilePassword\u此处
)pemfilePassword\此处
是您从已安装的voip证书导出.pem
文件时给出的密码。(请参阅第4点。)yourDeviceTokenID\u生成的\u带有更新\u推送\u凭证\u带有令牌\u此处
应替换为令牌
,令牌由PKPushRegistryDelegate
的方法生成。见下文
func-pushRegistry(registry:PKPushRegistry,didUpdate-pushCredentials:PKPushCredentials,for-type:PKPushType){
(iOS 13.4.1和Xcode版本11.4(11E146))即使不是iOS 13,iOS也会终止应用程序。苹果自己说,如果应用程序是iOS 13及更高版本开发的,它会终止,但在报告失败后仍会终止应用程序。我已经与苹果开发人员支持人员谈过,他们说只有iOS 13会这样做,但我仍然有错误。你需要获得这些(必需的参数)在呼叫无效推送中。我不确定这是否是解决方案,当应用程序处于后台模式时,也不会收到带有这些参数的VoIP推送,因为必须报告呼叫,并且报告呼叫需要这些字段,因此您必须修改推送的有效负载。VoIP推送是否表示传入呼叫?如果是,则需要通过CallKit报告传入呼叫。如果没有,那么您必须使用正常的推送通知系统。我使用推送传入和推送呼叫,也使用voip类型,这两种类型都是正常推送。在这两种情况下,它们都不会以backgorund模式到达。唯一的方法是将不影响呼叫的呼叫作为正常推送进行管理。您认为这是解决方案吗IONS也适用于VoIP推送,这些推送不是推送呼叫,而是仅具有个性化负载的推送?您不能将VoIP推送用于
let parts = pushCredentials.token.map { String(format: "%02.2hhx", $0) }
let token = parts.joined()
print("did update push credentials with token: \(token)") }