【问题标题】:ios pushkit end last call before reportnewIncommingCallios pushkit 在 reportnewIncommingCall 之前结束最后一次通话
【发布时间】:2020-09-23 09:03:46
【问题描述】:

我被困在如何在报告新来电之前结束所有最后一个通话,我的功能适用于 2 个通话,这意味着我可以在报告新通话之前结束第一个通话

但问题是下次报告后,结束调用函数抛出错误

这是我的代码:

// Handle incoming pushes
    func pushRegistry(_ registry: PKPushRegistry, didReceiveIncomingPushWith payload: PKPushPayload, for type: PKPushType, completion: @escaping () -> Void) {
//        print("Handle incoming pushes: \(payload.dictionaryPayload)")
        
        endCall(thenReportNewCallForUuid: UUID.init())
    }
    
    func reportNewCall(uuid : UUID){
        
        let config = CXProviderConfiguration(localizedName: "CallKitExample")
        config.includesCallsInRecents = true
        config.supportsVideo = true
        config.supportedHandleTypes = [.generic]
        config.iconTemplateImageData = UIImage(named: "logo_square")!.pngData()
        config.maximumCallGroups = 1
        config.maximumCallsPerCallGroup = 1
        
        
        let provider = CXProvider(configuration: config)
        provider.setDelegate(self, queue: nil)
        
        let update = CXCallUpdate()
        update.supportsHolding = false
        update.supportsGrouping = false
        update.supportsUngrouping = false
        update.remoteHandle = CXHandle(type: .generic, value: uuid.uuidString)
        update.hasVideo = true
        provider.reportNewIncomingCall(with: uuid, update: update, completion: { error in
            print("reportNewIncomingCall \(uuid) error: \(error)")
            
            UserDefaults.standard.set(uuid.uuidString, forKey: "CallUUID")
            UserDefaults.standard.synchronize()
        })
    }

func endCall(thenReportNewCallForUuid : UUID) {
        
        guard let lastCallUUIDString = UserDefaults.standard.string(forKey: "CallUUID"), !lastCallUUIDString.isEmpty  else{
            return
        }
        print("end uuid: \(lastCallUUIDString)")
        let call = UUID.init(uuidString: lastCallUUIDString)!
        
        let controller = CXCallController()
        let endTransaction = CXEndCallAction(call: call)
        let transaction = CXTransaction(action: endTransaction)
        controller.request(transaction, completion: { error in
            if let error = error {
                print("endcall Error: \(error)")
                self.reportNewCall(uuid: thenReportNewCallForUuid)
            } else {
                print("endcall Success")
                self.reportNewCall(uuid: thenReportNewCallForUuid)
            }
        })
    }

这是我得到的日志 + 错误

end uuid: CB91CCC6-7FCD-49D3-BE93-7A6581295B57
endcall Error: Error Domain=com.apple.CallKit.error.requesttransaction Code=2 "(null)" 
-> OK first time endcall error because no call 
reportNewIncomingCall 202DB031-23AE-46B6-91E9-3FBA708E07A7 error: nil


end uuid: 202DB031-23AE-46B6-91E9-3FBA708E07A7
endcall Success -> Matched call to end -> success
reportNewIncomingCall C45FEC0B-1320-4357-ADEF-7B7CA28D96C8 error: nil


end uuid: C45FEC0B-1320-4357-ADEF-7B7CA28D96C8
endcall Error: Error Domain=com.apple.CallKit.error.requesttransaction Code=4 "(null)"
-> Matched call to end -> FAILED
reportNewIncomingCall CBDBA75A-B263-49E5-9138-8D5CCA28ED9E error: nil

请标记重复的人显示正确答案?谢谢

有人面临同样的问题吗?请帮忙

【问题讨论】:

  • 不,兄弟,因为我有 3 个连续通话,第一个 -> 第二个(我成功结束第一个通话报告第二个来电)-> 第三个(错误结束第二个通话)-> 我有 2 个通话屏幕,然后需要按 2 次来关闭 2 个呼叫

标签: swift callkit pushkit


【解决方案1】:

我在您的代码中至少发现了几个问题。但是,在此之前,为什么每当您收到新的来电时就结束正在进行的通话?我只是好奇,因为它似乎不是一个很好的用户体验。

无论如何,我发现的问题如下:

  • 在每次新来电时,您都会实例化一个新的CXProvider。如documentation中所述:

VoIP 应用程序应该只创建一个 CXProvider 实例并将其存储以供全球使用。

  • 您不调用pushRegistry(_:didReceiveIncomingPushWith:type:completion) 方法的完成处理程序。您应该在 reportNewIncomingCall(with:update:completion:) 方法的完成处理程序中调用它。

我认为您面临的错误是由CXProvider 问题引起的。但是如果你不解决第二个问题,你可能会遇到另一个问题:系统会假设你没有报告新的来电,所以在几个电话之后,它会停止向你发送新的 VoIP 推送( this limitation 在 iOS 13 中首次引入)。

【讨论】:

  • 嗯,我搜索了很多 void manager,但找不到任何好的,你能提供一些教程吗?谢谢,我使用过 SpeakerBox,但在尝试管理通话时仍然有问题:(
  • 如果您还有其他问题,您可以发布其他问题,我(或其他人)可能会为您提供帮助。
【解决方案2】:

我遇到了同样的问题,并通过将 CXProvider、CXProfiderConfiguration 和 CXCallController 的实例化移动到 pushRegistry 函数之外和 AppDelegate 的 didFinishLaunchingWithOptions 部分内部来解决它,如下所示:

private func voipRegistration() {
    // Create a push registry object
    let mainQueue = DispatchQueue.main
    let voipRegistry: PKPushRegistry = PKPushRegistry(queue: mainQueue)
    voipRegistry.delegate = self
    voipRegistry.desiredPushTypes = [PKPushType.voIP]
    config.iconTemplateImageData = #imageLiteral(resourceName: "cometchat_white").pngData()
    config.includesCallsInRecents = false
    config.ringtoneSound = "ringtone.caf"
    config.supportsVideo = false
    provider = CXProvider.init(configuration: config)
    provider!.setDelegate(self, queue: nil)
   
}

您必须有一个 CXProvider 实例。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-08-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多