Incoming call issue using CallKit and PushKit

I'm developing a VoIP app using CallKit and PushKit framworks and I’m facing a strange issue that happens only sometimes and more consistently in older devices, moreover it seems to happen only when the app is closed and the iPhone is locked. The problem is that when someone tries to call me, I receive the “incoming call” VoIP push but the CallKit UI do not show up until a second push is received (e.g. “hang up” notification). So, what happens is that the iPhone starts ringing when it receives the “hang up” notification and of course the caller has already hanged up.


My guess is that when the iPhone receives a push notification has only a limited amount of cpu time to report the incoming call and in certain circumstances the app exceeds this time and gets stopped, so when the second push arrives (“hang up” notification) the app continues the execution from where it left off and shows the incoming call UI. Is that possible?


Any help would be much appreciated!

Upon further investigation, it turned out that the problem was probably caused by an early call to the incoming push completion handler. As stated by the Twilio team in a similar issue they had: “The issue happens when reporting the call to CallKit and calling the incoming-push completion handler at the same time (when the app is not in the foreground) [which is the natural thing to do in a CallKit/PushKit app - ed.]. For some reason the CallKit reporting method gets stuck and won't fire the completion block in this scenario. The fix relieves the problem by only calling the incoming-push-completion when the call is reported.”


The Apple documentation says: “Call the completion handler as soon as you have finished processing the payload”. To me, that is ambiguous. If, in the case of an incoming call, you mean “wait until the completion handler of reportNewIncomingCall(with:update:completion:) has been called”, please Apple be explicit about that.


I hope this will save someone from days of frustration and wasted work.

Thank you so much, this problem has troubled me all day, and I found a solution when I was about to get off work

Yes, I have changed the code according to marco's suggestion:

func pushRegistry(_ registry: PKPushRegistry, 
                      didReceiveIncomingPushWith payload: PKPushPayload,
                      for type: PKPushType,
                      completion: @escaping () -> Void) {
... some code

              self.provider?.reportNewIncomingCall(with: callPayload.uuid , update: update, completion: { error in
                // new code
                DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
                    completion()
                }
                
                // old code
//                completion()
            })

... some code
}

Amazing, It works perfectly. Thanks marco

Incoming call issue using CallKit and PushKit
 
 
Q