im stuck in how to ending all the last call before report a new incoming call, my function work for 2 call, it mean i can end the first call before report new call
But the problem is after next report, the end call function throw error
Here is my code:
// 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)
}
})
}
Here is log + error i got
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
Some one who mark duplicate please show the right answer? Thanks
Does someone facing same problem? Please help
I see at least a couple of issues in your code. But, before that, why are you ending the ongoing call whenever you receive a new incoming call? I'm just curious, because it doesn't seem to be a great user experience.
Anyway, the issues I've found are the following:
CXProvider
. As stated in the documentation:A VoIP app should create only one instance of CXProvider and store it for use globally.
pushRegistry(_:didReceiveIncomingPushWith:type:completion)
method. You should invoke it inside the completion handler of the reportNewIncomingCall(with:update:completion:)
method.I think that the errors you're facing are caused by the CXProvider
issue. But if you don't fix also the second issue you could incur in another problem: the system will suppose that you haven't reported a new incoming call and so, after a few calls, it will stop to send you new VoIP pushes (this limitation was first introduced in iOS 13).