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
61
12h
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
1.9k
Nov ’20
Determine difference between build/clean/archive in Scheme pre/post actions
When running scripts in the Scheme's build pre/post actions, I have been struggling to determine the difference between when the action has been run through a Build, Clean or Archive. The motivation in this case is that I have a Build Post-action that increments build numbers after building^[1]. So far the best solution I have come up with is to select the "Provide build settings from" and then specify my target. This way I can detemine some things from the environment variables in the script, for example: ACTION is empty when building/cleaning both Debug and Release builds, but set to "install" when archiving. CONFIGURATION is set to Debug/Release when building/cleaning Debug/Release builds respectively. The biggest gripe I have is that I haven't found a way to determine if a clean is being run vs a build - especially if you relate it to the motivating example that is incrementing build numbers, you don't want them to increment on a clean! Does anyone know of a way to do this? Alternatively, does anyone know if it is possible to specify Xcode configuration variables that are only set for clean vs build, much like you can restrict variables to Debug/Release or certain architectures? [1] The reason for this being a post action is my current solution in place is to leave a market file in /tmp/ in a build-phase run script, and then when the Build Post-action runs I can detect for the presence of that file to know that this was a build. This however does not solve the issue for pre-action scripts which would (in my opinion) be a more ideal place to increment the build number.
1
1
464
Jul ’20