Network privacy permission check

Is there an API to check to see if the user has previously granted or more importantly declined network permission? I am not seeing anything in the resources of the video.
No, there isn't an API to check the status overall. However, the various connection APIs you use that can get affected will let you know when they're waiting for a network (URLSession or NWConnection).

If you have a case where you'd like to know if your app doesn't have permission, can you describe it? Is this for using Bonjour, or a direct connection use case?
I was also wondering the same thing. This would be something that is super helpful for our automated UI testing. In our current testing application we trigger camera and microphone permission prompts before we run our test suite so we can ensure that the tests that depend on camera and microphone capture will work.

Now, we run into the issue where if our SDK (which builds upon WebRTC) decides that a local network Peer to Peer connection is most suitable, it will cause the Local Network permission alert to appear. Its all dependent on the environment at the given time, and being that we test in a device farm on fresh devices, this is something that could be tricky to manage. I was under the assumption that the permission would be similar to AVCaptureDevice authorizationStatusForMediaType: where it would return things like AVAuthorizationStatusNotDetermined, AVAuthorizationStatusAuthorized and AVAuthorizationStatusDenied.

If the user chooses to not allow permissions, we have no way in code to do something different, as we... don't know... that they said no previously. If we were able to detect that they denied the permission, we could, for instance, force WebRTC to use TURN instead and still achieve functionality.

I am looking at this from two angles, now that I type this. One is about allowing us the ability to manage permissions in automated tests. The second is for allowing a better experience to our customers' customers who decline local network permissions. If we are unable to know that they declined the permission, we can't talk alternative approaches to providing a useable experience.
Furthering the testing question, I just watched the "Handle interruptions and alerts in UI tests" session and they discussed the addition of the resetAuthorizationStatusForResource: method on XCUIApplication. This method takes an enum which allows a UI test to reset the authorization status for various system permissions that the OS requests of the user. Looking at the XCUIProtectedResource enum, there is no such enum for the Local Network privacy option.


With WebRTC there is a possibility of mDNS being used to discover Peers (not via the Bonjour APIs). Other times, TCP or UDP candidates might be used to send and receive media within the scope of the local network. In strict client to server streaming cases it may be easy rule out local network use but other times it is not since the protocol is designed for general Peer-to-Peer connectivity.

Since POSIX networking APIs are being used by WebRTC, it would be nice for software developers to have a way to determine the authorization status before hand, and if the status changes. We can take actions like not gathering host candidates if permission is not granted for the local network. Alternatively we could filter any candidates that are gathered so that use of the local network is avoided.
Very good feedback, thank you! Can you file that on FeedbackAssistant for XCUIProtectedResource and post the number here?

For active use not during testing, we generally recommend against pre-flight checks wherever possible, however the error codes returned from attempts to use local network resources should provide enough information to display/do the right thing if such access is critical, or appropriately handle using only the remaining options if that particular resource isn’t the only option for achieving the user’s intent. If you can find places where this isn’t the case, we’d love to know about it!
I have created Feedback FB7801261 which also includes the request for XCUIProtectedResource.

As ceagleston and I explained during our lab session as well as in the ticket above, there are some issues with the approach of fire and check later for errors when combined with WebRTC and Interactive Connectivity Establishment (ICE) which will cause issues which could be circumvented if we know beforehand that a user has denied local network access. Please review Feedback FB7801261. If you have further questions regarding the use case, please don't hesitate to reach out. Thank you!
It seems absolutely necessary to have a check like this for creating an MCNearbyServiceAdvertiser & Browser.

I hope it’s added otherwise this could affect users’ in app experiences really negatively if we can’t check before creating these experiences, especially if it’s being created within an AR scene for example.
I was hoping the NSURLSession could give us a good error code to indicate user denies the local network permission. But seems like it's giving out the generic NSURLErrorNotConnectedToInternet = -1009 which we can't really tell whether the user actually has internet down OR denies the local network access.
To Framework Engineer,
Without having any direct method to inquire if the local network permission is available, it is not possible for us to change the point of triggering local network calls. Let say an App does not want to send local network calls on App launch if local network permission is not available. Rather, initiate the local network calls only when user performs a specific user action such as tap on a button. This will help to provide the context to the user why local network permission is required. If local permission is available, we would prefer to send the local network messages on App launch itself.
Checking if the local permission is possible by sending local network message on App launch (lets say mdns request message) but as soon as the mdns message will be sent, the permission dialog will be prompted to the user. That is the reason, We do not want to send the local network message until permission is available or user performs specific action.
Please let us know if such an API may be exposed in iOS 14 to check the local network permission status.
We have filed FB7801261 against 14.0 beta1, and there has been no movement on APIs as of 14.0 beta3. There is quite a bit of information on the ticket from both RCP and myself about the use case and how the new APIs differ from existing permissions APIs in CoreLocation and AVFoundation that we rely on every day.

Responding to the comments from Apple Frameworks Engineer:

If you have a case where you'd like to know if your app doesn't have permission, can you describe it? Is this for using Bonjour, or a direct connection use case?

A direct connection. As we have tried to explain there are thousands of apps that use WebRTC, which under the hood uses ICE. The most common configuration of ICE attempts to establish a direct connection with POSIX TCP and UDP sockets. When a PeerConnection is negotiated, the Peers are ignorant of their network topology and exchange candidates, testing pairs in an attempt to establish a low latency connection on the cheapest network route possible. Traffic may go through a relay server, but this is often the last check performed due to the time needed to perform TURN allocations and grant permissions for the peers.

The first check being performed is often on the pairing of host candidates from each device. If permissions are declined then this check kills the socket and WebRTC does not recover it effectively. I will stop here, as it appears that I am not allowed to attach my sequence diagram. I believe we included it in the FB, but I will add it again to be sure.

We can skip the host candidate checks (and optional mDNS discovery phase) if permissions are declined, but not without an API to check the state of the user's permissions and reconfigure our Ice agent accordingly.
I had one more thought about non-recoverable scenarios as I investigate this problem further in beta3.

For active use not during testing, we generally recommend against pre-flight checks wherever possible, however the error codes returned from attempts to use local network resources should provide enough information to display/do the right thing if such access is critical, or appropriately handle using only the remaining options if that particular resource isn’t the only option for achieving the user’s intent. If you can find places where this isn’t the case, we’d love to know about it!

If the Ice transport protocol is UDP then the host, server reflexive and relay candidates share the same base transport address (protocol:ip:port). This means that terminal socket errors received due to host candidate checks can cause the stun and relay candidates to never be gathered. Using a pre-flight permissions check would allow us to configure the agent so that host checks are avoided and the UDP socket is not closed. I will investigate handling the socket level error, but this is a not insignificant change to a complex and cross-platform code base.

The relationship between the candidates is demonstrated in rfc8445-2.1. For the sake of discussion imagine that candidates are tested in the order of X:x, X1':x1', Y:y. The process only reaches X:x if the first check uses the local network.

To Internet
Code Block
|
|
| /------------ Relayed
Y:y | / Address
+--------+
| |
| TURN |
| Server |
| |
+--------+
|
|
| /------------ Server
X1':x1'|/ Reflexive
+------------+ Address
| NAT |
+------------+
|
| /------------ Local
X:x |/ Address
+--------+
| |
| Agent |
| |
+--------+
Code Block
Figure 2: Candidate Relationships
Hello Framework Engineer, I have an additional use case where an API for checking the Local Network permission would be useful: support for Chromecast and multicast-discovered speakers.

Here are some issues we run into without such API

1) If we have a trigger point for the "<App> would like to find and connect to devices on your local network" and the user denies the permission, forget they did it, and then come back to the trigger point, we would like to be able to remind them and offer to bring them to our app Settings which is impossible without knowing the state of the permission.

2) If the user has previously granted permission at the trigger point and we were able to test the state of the permission at app launch, we could kick off the device discovery for them without waiting for them to come back to the trigger point. This is critical for reconnect scenarios, i.e., the app attempts to automatically reconnect to a Casting session that existed last time it was shut down. Without the API to check the permission our feature will be broken.

3) Some frameworks create singletons and will throw exceptions if we attempt to initialize them more than once. We would like to know we have the necessary permission to safely initialize those singletons.

4) Some frameworks may fail internally on the Local Network permission and throw obfuscated errors. In that case we wouldn't be able to tell if the failure is caused by the lack of permission and we can't provide useful feedback for our user. Unless we assume that any error may be caused by the lack of permission and tell the user something like "Please, make sure the Local Network permission is enabled in your iPhone's Settings", which is less than ideal.

I hope It's possible to have this API so we don't have to resort to complex guessing. Please, help.
Responding to the comments from Apple Frameworks Engineer:


If you have a case where you'd like to know if your app doesn't have permission, can you describe it? Is this for using Bonjour, or a direct connection use case?

I have an app that controls a hardware device that we manufacture and sell. In order to find the hardware on the network, we send a UDP broadcast with a message for our hardware, and the hardware responds with a message back so that we can get an endpoint to send calls directly to the hardware. The UDP broadcast triggers the request for Local Network permissions, and if the user chooses not to accept it, we will never find their hardware device, and we do not have any tools for diagnosing the issue for them. We're going to have to have a generic error message anytime the hardware is not found telling users to make sure the hardware is connected AND go into Settings on their iOS device and ensure that Local Permissions is turned on for the app. We will warn the user ahead of seeing the request that they need to accept it, but there's always ones that don't, and once that gets off the rails there's no good way to help the user back on the rails. It ends up in a terrible experience for the user.

A heavy +1 to get an authorization status API for local network access. I filed FB8216410 with more feedback and use cases.
I agree, +1 to get an authorization status API for local network access. I filed FB8226110 with more feedback and use cases.
Agree. Without the authorization status API, my customer will complain about the hardware device connectivity issue, reply negative comment at online store, or sales return. We will never know the actual issue is the customer disable the local network access, by mistake, or forgot, or on purpose.

If you have a case where you'd like to know if your app doesn't have permission, can you describe it? Is this for using Bonjour, or a direct connection use case?

Hi Frameworks engineer! I have an app in the store which is used to control Sony's line of mirrorless and point and shoot cameras. The whole app requires this permission:
  1. We need to send UDP messages on the local network (rather, the camera's network) and receive them from the camera for device discovery.

  2. Once the device is discovered to control it we need to setup a socket connection (PTP/IP control) or communicate with a http API on the camera's network.

All of this is an absolute nightmare if we have to factor in this new permission, especially as lots of these APIs send errors in different ways, and in some cases URLSession errors which don't even explicitly say that the issue is local network permissions as others have pointed out!



If you have a case where you'd like to know if your app doesn't have permission, can you describe it? Is this for using Bonjour, or a direct connection use case?

I have an app that should connect to device AP to provision it via HTTP/HTTPS.
While iOS reconnects from home to device AP NSURLErrorNotConnectedToInternet error are quite expected. With existing API there is no way to distinguish "still connecting" and "no permission" state.

  • 1... I am also in need for a permissions API. I have an app that controls Hue lights, and if the user revoked permission or never granted it, the app needs to be able to communicate this to the user. The absence of such an API is not only not in line with other permission APIs existing, it also means that we cannot inform our users about the actual issue nor give him information about how to work around it!

Generic errors like having no internet connections are not sufficient! A blocked local network access is a third state and must be indicated.

I agree that certain bad behaving apps need to get treated properly, but this is again a new API (background geofencing was the other) that is missing proper handling for certain valid cases. If you choose to add limited permissions, please work through all possible cases, and more importantly, please add and modify necessary functions BEFORE the golden master. That would be really helpful!
  • 1... I am also in need for a permissions API. I have an app that controls Hue lights, and if the user revoked permission or never granted it, the app needs to be able to communicate this to the user. The absence of such an API is not only not in line with other permission APIs existing, it also means that we cannot inform our users about the actual issue nor give him information about how to work around it!

Generic errors like having no internet connections are not sufficient! A blocked local network access is a third state and must be indicated.

I agree that certain bad behaving apps need to get treated properly, but this is again a new API (background geofencing was the other) that is missing proper handling for certain valid cases. If you choose to add limited permissions, please work through all possible cases, and more importantly, please add and modify necessary functions BEFORE the golden master. That would be really helpful!
In my opinion, you REALLY need to add an API where developers can query the status of the Local Network permission. Otherwise it is near impossible to make a good user experience, particularly considering that the access can be revoked at a later time. NSURLSession only returns the error code -1009 "The Internet connection appears to be offline.”, and if that occurs, how should we handle that?

Also, your logic now assumes that permission should be granted at the time the request is sent, but what if you need to ask for permission in advance? For example, let’s say an app needs to send a WakeOnLan packet to a LAN device, not now, but at a later time, how should the app handle that?

As an example, our application uses Bluetooth LE to communicate with sensors and when those sensors are triggered the app is then woken up (In the background) to forwards commands to Smart Home devices on the LAN (such as Philips Hue lights). Since this happens in the background iOS will not display a permission dialog, so the user will not be able to allow permission. The app will not know, at this time, if the request failed due to lack of permission or if the iOS device is not connected to the LAN.

We can not be expected to always display an error notification saying “You either have no internet connection or you don’t have Local Network permission.”. That would be a terrible user experience!

Lastly, the fact that you do have the option to both ask for, and check, permissions on other API’s clearly shows that Apple knows that it is needed. Just look at AVCaptureSession and CLLocationManager.

If you can find places where this isn’t the case, we’d love to know about it!

When we need to discover another service, to get the domain name and port to use rest API. We haven't error from
Code Block
NetServiceBrowser.searchForServices

Only no service found, while we are on the local network.
In this case we can't know if we haven't services or permission and an API is needed to know the state of the local network permission.

Especially that this access is critical to our app.
Yes, what is an app supposed to do if its entire functionality is dependent upon local network access, and the user inadvertently turned off the access permission? All other access permissions (Photos, Notifications, etc.) have API that allow an app to query the permission status.
@Frameworks Engineer We have apps that configure household appliances through local calls, if the user does not approve they will never be able to configure the appliance.
without an API that tells us that the user hasn't approved how do we block the user and tell him he can't continue?
I think the (current) "best" answer is that we need to move to NWBrowser:

https://developer.apple.com/forums/thread/658103
Network privacy permission check
 
 
Q