Post

Replies

Boosts

Views

Activity

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?
1
0
451
Jan ’25
Observers observe NEVPNStatusDidChange multiple times when loading NEPacketTunnelProvider more than once
I have an app that implements my own Packet Tunnel Provider, and to my knowledge everything I do is working as intended. However, I came across an issue with NEVPNStatusDidChange NotificationCentre observations when calling the following function multiple times:NETunnelProviderManager:loadAllFromPreferences(completionHandler:) From the documentation: You must call loadFromPreferences(completionHandler:): at least once before calling this method the first time after your app launches. As a result of this note, an early implementation I had took a very conservative approach; calling loadFromPreferences(completionHandler:): every time before operating on my NEPacketTunnelProvider. This was done by a helper function which was run as a precursor to any operation done to the manager, ensuring that the latest manager was being used every time. This looked something like:func myStartVPN() { 		loadHelper { (manager: NEPacketTunnelProvider, error: Error?) in /* handle errors */ startVPN(withManager: manager) } } When using this approach, I noticed that observers that look for NEVPNStatusDidChange events got triggered multiple times for these events, with the number of times it being triggered machine the number of times I called loadAllFromPreferences(). Chronologically speaking I was experiencing something along the lines of Appendix 1. As a result of this issue, my production equivalent of loadHelper(), above, only calls load once the first time a manager is requied, and then subsequent operations on the manager use a cached value - a bit like a standard lazy field. Obviously this is not a big issue as I have a working solution, however I haven't been able to work out what causes this behaviour - does anyone have any ideas? Could it be a general Swift/Objective C pitfall with KVO that I am not aware of? Could it be some sort of issue with NetworkExtension/my approach? (I'm thinking some references might not be being cleaned up every time I load?) Appendix 1 Previously set up NEPacketTunnelProvider* loadAllFromPreferences() followed by saveManager() Recieve NEVPNStatusDidChange - Disconnected loadAllFromPreferences() followed by startVPNTunnel() Recieve NEVPNStatusDidChange - Connecting x2 Recieve NEVPNStatusDidChange - Connected x2 loadAllFromPreferences() followed by stopVPNTunnel() Recieve NEVPNStatusDidChange - Disconnecting x3 Recieve NEVPNStatusDidChange - Disconnected x3 loadAllFromPreferences() followed by startVPNTunnel() Recieve NEVPNStatusDidChange - Connecting x4 Recieve NEVPNStatusDidChange - Connected x4 loadAllFromPreferences() followed by stopVPNTunnel() Recieve NEVPNStatusDidChange - Disconnecting x5 Recieve NEVPNStatusDidChange - Disconnected x5
7
0
2.1k
Nov ’20