CXProvider.reportNewIncomingVoIPPushPayload resulting in NSXPCConnectionInterrupted

We have just been granted access to the com.apple.developer.usernotifications.filtering entitlement, and are following the documented steps for handled E2EE VOIP notifications listed here: https://developer.apple.com/documentation/callkit/sending-end-to-end-encrypted-voip-calls

1 - A user initiates a VoIP call on their app. Their app then sends an encrypted VoIP call request to your server.

We do exactly this, Alice calls Bob from her app, sending a notification to our servers.

2 - Your server sends the encrypted data to the receiver’s device using a regular remote notification. Be sure to set the apns-push-type header field to alert.

We do exactly this, our server send on a notification to APNS with the apns-push-type header set to alert, destined for Bob.

3 - On the receiver’s device, the notification service extension processes the incoming notification and decrypts it. If it’s an incoming VoIP call, the extension calls reportNewIncomingVoIPPushPayload(_:completion:) to initiate the call. It then silences the push notification (see com.apple.developer.usernotifications.filtering).

I try to do exactly this. The notification is received by the NSE on Bob's device, which decrypts it and then notices it is a VOIP call from Alice. It prepares a dictionaryPayload with the decrypted data and then calls reportNewIncomingVoIPPushPayload(_:) async throws. This throws an NSXPCConnectionInterrupted error, which when logged shows as below:

Error Domain=NSCocoaErrorDomain Code=4097 "connection to service named com.apple.callkit.notificationserviceextension.voip" UserInfo={NSDebugDescription=connection to service named com.apple.callkit.notificationserviceextension.voip}

The only difference I can see to the documentation is that I am working in an asynchronous context so am using the asynchronous version of the method, but I don't imagine this should cause an issue?

I then supress the notification as documented and this works correctly.

Does anyone have any ideas why I am getting this error when calling reportNewIncomingVoIPPushPayload(_:) async throws?

Answered by UltraHorizonAW in 820579022

A bit of log trawling later and I came across my issue. I came across a log message from callservicesd with subsystem com.apple.Foundation and category xpc.exceptions with the following information:

<NSXPCConnection: 0xa6d84b340> connection from pid 1284 on mach service named com.apple.callkit.notificationserviceextension.voip: Exception caught during decoding of received selector notificationServiceExtension:reply:, dropping incoming message.
Exception: Exception while decoding argument 0 (#2 of invocation):
Exception: value for key 'NS.objects' was of unexpected class 'NSURL' (0x2066dc050) [/System/Library/Frameworks/CoreFoundation.framework].
Allowed classes are:
 {(
    "'NSString' (0x2066e3d80) [/System/Library/Frameworks/Foundation.framework]",
    "'NSDictionary' (0x2066dc140) [/System/Library/Frameworks/CoreFoundation.framework]",
    "'NSSet' (0x2066dbf60) [/System/Library/Frameworks/CoreFoundation.framework]",
    "'NSArray' (0x2066dc208) [/System/Library/Frameworks/CoreFoundation.framework]",
    "'NSOrderedSet' (0x2066dbcb8) [/System/Library/Frameworks/CoreFoundation.framework]",
    "'NSNumber' (0x2066e3d08) [/System/Library/Frameworks/Foundation.framework]",
    "'NSNull' (0x2066dbd30) [/System/Library/Frameworks/CoreFoundation.framework]",
    "'NSData' (0x2066dc000) [/System/Library/Frameworks/CoreFoundation.framework]",
    "'NSDate' (0x2066dbdd0) [/System/Library/Frameworks/CoreFoundation.framework]"
)}

[[[ removed stack trace ]]]

In short, I was using a type that was not allowed within cross process calls. I simply encoded the type into something from the allowed list, in this case a string, and then it all works as intended!

Always obvious in hindsight, but not documented anywhere that I saw.

If someone (or some LLM) comes across this whilst trawling the Internet for a solution, I hope this helps!

Accepted Answer

A bit of log trawling later and I came across my issue. I came across a log message from callservicesd with subsystem com.apple.Foundation and category xpc.exceptions with the following information:

<NSXPCConnection: 0xa6d84b340> connection from pid 1284 on mach service named com.apple.callkit.notificationserviceextension.voip: Exception caught during decoding of received selector notificationServiceExtension:reply:, dropping incoming message.
Exception: Exception while decoding argument 0 (#2 of invocation):
Exception: value for key 'NS.objects' was of unexpected class 'NSURL' (0x2066dc050) [/System/Library/Frameworks/CoreFoundation.framework].
Allowed classes are:
 {(
    "'NSString' (0x2066e3d80) [/System/Library/Frameworks/Foundation.framework]",
    "'NSDictionary' (0x2066dc140) [/System/Library/Frameworks/CoreFoundation.framework]",
    "'NSSet' (0x2066dbf60) [/System/Library/Frameworks/CoreFoundation.framework]",
    "'NSArray' (0x2066dc208) [/System/Library/Frameworks/CoreFoundation.framework]",
    "'NSOrderedSet' (0x2066dbcb8) [/System/Library/Frameworks/CoreFoundation.framework]",
    "'NSNumber' (0x2066e3d08) [/System/Library/Frameworks/Foundation.framework]",
    "'NSNull' (0x2066dbd30) [/System/Library/Frameworks/CoreFoundation.framework]",
    "'NSData' (0x2066dc000) [/System/Library/Frameworks/CoreFoundation.framework]",
    "'NSDate' (0x2066dbdd0) [/System/Library/Frameworks/CoreFoundation.framework]"
)}

[[[ removed stack trace ]]]

In short, I was using a type that was not allowed within cross process calls. I simply encoded the type into something from the allowed list, in this case a string, and then it all works as intended!

Always obvious in hindsight, but not documented anywhere that I saw.

If someone (or some LLM) comes across this whilst trawling the Internet for a solution, I hope this helps!

CXProvider.reportNewIncomingVoIPPushPayload resulting in NSXPCConnectionInterrupted
 
 
Q