How to use the new iOS26.4 method: pushRegistry(_:didReceiveIncomingVoIPPushWith:metadata:withCompletionHandler:)

I have a VoIP app, now try to implement the new method which support the "PKVoIPPushMetadata" in iOS 26.4.

Code as below:

    /// iOS 26.4+ (SDK with `PKVoIPPushMetadata`): prefer this path for VoIP per Apple; completion is `@Sendable` on supported SDKs.
    @available(iOS 26.4, *)
    func pushRegistry(_ registry: PKPushRegistry, didReceiveIncomingVoIPPushWith payload: PKPushPayload, metadata: PKVoIPPushMetadata, withCompletionHandler completion: @escaping @Sendable () -> Void) {
        print("willtest: didReceiveIncomingVoIPPushWith: metadata=\(metadata)")
        handleVoIPPush(payload: payload, metadataMustReport: metadata.mustReport, completion: completion)
    }

    func pushRegistry(_ registry: PKPushRegistry, didReceiveIncomingPushWith payload: PKPushPayload, for type: PKPushType, completion: @escaping () -> Void) {
        print("willtest: didReceiveIncomingPushWith: PKPushType=\(type)")
        handleVoIPPush(payload: payload, metadataMustReport: nil, completion: completion)
    }

But the voip push only goes to the old method on my iOS26.4 device(iPhone17). And it will go to the new method after I delete the old method.

So how can I use this method in my app? I must support iOS16+ versions.

Answered by DTS Engineer in 885974022

But the VoIP push only goes to the old method on my iOS26.4 device (iPhone17).

Huh. That's very strange, as the fact that it works when you delete the old method:

And it will go to the new method after I delete the old method.

...means that the PushKit implementation itself works fine and that this is actually something about the Swift availability declaration. Can you file a bug on this, upload the code for your delegate class, and then post that bug number back here? I'm not sure what's going on and I'd like to figure that out.

Having said that:

So how can I use this method in my app?

...if you want to get something working/ship "now", then I see two options:

  1. Implement this particular delegate in Objective-C, not Swift. As I mentioned above, if it works when you delete the old method, then the problem has to be with the Swift availability declaration. Objective-C’s handling of this is much simpler, so this cannot happen there.

  2. If you want to stick to Swift, then duplicate your existing delegate code and use that to create two different delegate classes. One implements the old method, the other the new method, and you create and assign the correct delegate implementation by checking the system version when your app launches. It can't call the wrong delegate if your app doesn't implement that delegate.

I may be able to find a better solution once I see your full code, but either of the two options above will let you ship immediately without relying on anything unusual or tricky.

__
Kevin Elliott
DTS Engineer, CoreOS/Hardware

But the VoIP push only goes to the old method on my iOS26.4 device (iPhone17).

Huh. That's very strange, as the fact that it works when you delete the old method:

And it will go to the new method after I delete the old method.

...means that the PushKit implementation itself works fine and that this is actually something about the Swift availability declaration. Can you file a bug on this, upload the code for your delegate class, and then post that bug number back here? I'm not sure what's going on and I'd like to figure that out.

Having said that:

So how can I use this method in my app?

...if you want to get something working/ship "now", then I see two options:

  1. Implement this particular delegate in Objective-C, not Swift. As I mentioned above, if it works when you delete the old method, then the problem has to be with the Swift availability declaration. Objective-C’s handling of this is much simpler, so this cannot happen there.

  2. If you want to stick to Swift, then duplicate your existing delegate code and use that to create two different delegate classes. One implements the old method, the other the new method, and you create and assign the correct delegate implementation by checking the system version when your app launches. It can't call the wrong delegate if your app doesn't implement that delegate.

I may be able to find a better solution once I see your full code, but either of the two options above will let you ship immediately without relying on anything unusual or tricky.

__
Kevin Elliott
DTS Engineer, CoreOS/Hardware

Hi, Kevin

I updated my iOS to 26.4.2, then it works fine:

  1. iPhone17(iOS 26.4.2) goes to the new method.
  2. iPhone12PM (iOS 18.7.2) goes to the old method.

Then I can continue my test.

btw, I have another question about the APNs on iOS26.4 in the thread: https://developer.apple.com/forums/thread/823102 The APNs delay to send notification on iOS 26.4

Please help to check or ask other dev to check. Thanks.

How to use the new iOS26.4 method: pushRegistry(_:didReceiveIncomingVoIPPushWith:metadata:withCompletionHandler:)
 
 
Q