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.

Replies

There needs to be a simple status check for this similar to other settings.

Also, it would be a much better user experience if we could prompt for a specific permission directly instead of just dumping them in our app settings page. Users are often not technical and some apps have a lot of configuration options that can be confusing when they just need to change one setting.
@Frameworks Engineer

We're using NetServiceBrowser from NSNetServices. But it does not return an error code telling us about the missing permission if the user has rejected the permission.
This API is not deprecated and it even got a new error code if the configuration in the Info.Plist is not present. I think this needs to return an error if you try to browse and the user has rejected.
Switching to NWBrowser - which was only added with iOS 13 leaves us with the hassle of having to use two APIs in parallel. Both of them not deprecated.
Please just add a proper error to NetServiceBrowser
I've found an approach that might work for you as well: Get the local IP address of the iOS device. If you can't get it, you're not in WiFi. You will be able to get it even when no local network permissions are there!
Now ping your own address. It will succeed in case of granted permissions. It fails to send the packet if there is no local network authorization. SimplePing is an example ping implementation and will fail with didFailToSendPacket: in such a case.

I couldn't test a fresh install yet, but it's working properly when looking for disabled local network access. Hope this helps!
Update to my post: So pinging ourselves also triggers the network access dialogue (where localizing NSLocalNetworkUsageDescription doesn't work in XCode 12 GM / iOS 14 GM - be aware, fill out at least the English text in info.plist!).

But pinging can at least confirm if the user has disabled the local network access AFTERWARDS. So you should probably go this way: Let the user confirm local network access, e.g. by doing such a ping. If you want to confirm that the user actually selected "yes", do the ping e.g every second until it succeeds. If you need to know if the user denied it, I think it's possibly to query the view hierarchy for the presence of a dialogue.

Apple, you may read this: I'm not sure WHY such an API has been kept out. But as we need to find solutions, we need to do such hacks. Fortunately they work in most cases. But if the absence of such an API has the background to add some "fuzziness" about the user's intentions, you see that in the end it's possible to do it anyway.

From my perspective, it is not understandable why such an API is missing and why we need to do several hacks to achieve what should have been part of the iOS 14 release. The absence of such an API is inconsistent with the other permission APIs, and as you see there are many reasons why such an API should also be part of the iOS 14 release. Giving that even the permission localization doesn't work leaves the impression of all of this thrown together in haste.
Well this API was released without implementing any of the feedback that was posted by the developer community. Unfortunately, the end result is iOS 14 has degraded the UX of our app severely.

Our application connects to a user's PC over a LAN connection for the purpose of Remote Desktop. In all other versions of iOS, we identify host candidates and establish a connection -- this takes no more than a second, and the end-result is a direct connection to the user's machine.

In iOS 14 the connection outright fails because we are unable to check if this permission has been granted nor can we request it ourselves. Further, due to NAT hair pinning if a connection is established to the LAN via a public internet address, the connection is unstable; so a user is going to blame our app for degraded performance.

I'm baffled why this seems to be one of the only permissions APIs that has no way to determine if it has been granted.

Well this is frustrating. Our application relies on local network access and we'll have to do some hacks to find if the user has denied access as well.

Definitely harmful to user experience for my apps, with or without this hack.
  • 1

This is just a quick post to say that Apple is definitely listening here. There have been developments in this space but I can’t post any details yet. Partly that’s on me — I simply haven’t had time to catch up on the latest developments — and partly that’s because, as per standard Apple policy, I can’t comment about The Future™ (even when it’s The Near Future™).

If someone would care to open a DTS tech support incident about this, that’ll allow me to allocate more time to it.

IMPORTANT If you do that, please post a note here so that I don’t get a bazillion incidents. I’ll make sure to update this thread with the details.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@apple.com"

If you do that, please post a note here so that I don’t get a
bazillion incidents.

Amazingly enough, someone not on this thread managed to open a DTS tech support incident before anyone here. I’ll be working that over the next few days and post a copy of my results here.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@apple.com"
@eskimo: Thanks for listening! (and it wasn't me, either)

One last hint, because I DID implement an own authorization handler by the description I have given (and it works):
You will be able to fairly reliably detect the presence of the authorization dialogue by listening to:
UIApplicationWillResignActiveNotification and
UIApplicationDidBecomeActiveNotification

So if you are in the process of requesting network access, the app resigning active and becoming active again is a fairly good hint for the dialogue being shown and removed. After it has been shown and the user permitted local access, your ping will succeed. If it has been shown and your ping still fails, the user has very likely denied the request.
Looking for a window, as suggested earlier, doesn't work.

I'm open for improvement suggestions, as these notifications may also come up in the event of e.g. a call, or another system dialogue.
@eskimo Is that DTS request that you mentioned 747163779? I'm guessing not, but that was meeee. Figured out that -65555 error when asking dns_sd.h to do anything can be fixed by adding NSLocalNetworkUsageDescription and NSBonjourServices to Info.plist.

Is that DTS request that you mentioned 747163779?

Nope. Your request has landed in Matt’s queue.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@apple.com"
I've implemented @commanderk's approach and while it is does work, it's not the robust solution that an API would provide.

So:
1) @eskimo - anything you can tell us on when to expect an API solution (even "soon" or "not soon" would help).
2) @commanderk - any improvements since your post 3 weeks ago?
Best solution I've found is to use the .waiting state from NWBrowser. Ping the local network using NWBrowser and track the browser state using stateUpdateHandler, or just manually check the state when necessary. If the user denies access you will get the .waiting state.

See: https://developer.apple.com/forums/thread/658151

Note: You will need the com.apple.developer.networking.multicast entitlement, which must be requested from Apple. Without this entitlement you will always get the .denied state even if the user gives access. You will also need Xcode 12.

Best solution I've found is to use the .waiting state from
NWBrowser.

That is, indeed, one of the better options for this. For more info, see FAQ-9 in my Local Network Privacy FAQ.

Note You will need the com.apple.developer.networking.multicast
entitlement

That’s not my experience. There are circumstances where Bonjour requires this entitlement (see FAQ-4 in the above-mentioned post) but running an NWBrowser for a specific service type is not one of them.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@apple.com"
Hey eskimo,

Per FAQ-9 we can detect this via NWBrowser or kDNSServiceErr_PolicyDenied. The former requires Swift, the latter seems to require using dnssd.

For those of us using NSNetServiceBrowser there appears to be no solution.

You mentioned that Apple is listening here - without divulging any details, can you say whether or not there will be a solution for the NSNetServiceBrowser crowd at an undisclosed point in the future?

A simple yes or no will suffice - I just need to know if I need to move over to Swift/dnssd to solve this problem and deliver a better UX for my users.

Thanks for all your work on this!