NWPathMonitor.pathUpdateHandler behavior

In my case there are three interfaces. I had a mental model that I now believe is incorrect.

If any of the 3 interfaces is "satisfied", then I get one message telling me so. I guess if that one interface goes down, then I should get a second message that tells me that (this is hard to test as Xcode keeps disconnecting from my device when I switch to Settings to change things).

in my case, wifi and cellular are both on. I launch the app, get notified that wifi is satisfied, but nothing on cellular.

So my guess is there is a hierarchy: wired, wifi, and cellular. If the highest priority path is available, the others are assumed "off" since you have a path. Thus, you will never get "satisfied" for more than one path.

Correct?

Answered by DTS Engineer in 816792022
Because we allow massive data to flow in either direction, we also condition on cellular

This results in a TOCTTOU window, which is one of the specific reasons why we recommend against using preflighting. A better approach is to apply constraints to your requests. That way they’ll never go over the wrong interface.

Also, we recommend against using Wi-Fi / WWAN for this, but rather use the expensive / inexpensive constraint. Without that, a user on truly unlimited WWAN will not be artificially constrained. Indeed, many such users are never on Wi-Fi.

We have a techtalk, Adapt to changing network conditions, that goes into this stuff in depth.

Share and Enjoy

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

It’s hard to answer this without know how you constructed the NWPathMonitor instance.

Also, what are you using these results for?

We generally discourage folks from using NWPathMonitor. It’s not that the API is broken but rather than the whole concept is fundamentally suspect. The only way to tell whether you can talk to someone across the Internet is to try it.

this is hard to test as Xcode keeps disconnecting from my device when I switch to Settings to change things

Yeah, that can be tricky. If you’re turning interfaces off and on then I’ve found that it’s best to run outside of Xcode and render the results to a small test UI. You can also log to the system log and then pick that up once you’ve re-enabled networking.

Share and Enjoy

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

Part of the code:

        let queue = DispatchQueue(label: "NetworkManager")
        ssPathMonitor.start(queue: queue)
        ssPathMonitor.pathUpdateHandler = { path in
            DispatchQueue.main.async {
                let internetWifiAvailableOld = self.internetWifiAvailable
                let internetCellularAvailableOld = self.internetCellularAvailable
                let internetEthernetAvailableOld = self.internetEthernetAvailable
                self.internetWifiAvailable = path.usesInterfaceType(.wifi)
                self.internetCellularAvailable = path.usesInterfaceType(.cellular)
                self.internetEthernetAvailable = path.usesInterfaceType(.wiredEthernet)
//                Log("NetworkManager satisfied:", path.status == .satisfied ? "YES" : "no" , "WIFI:", self.internetWifiAvailable, "CELL:", self.internetCellularAvailable, "ETHERNET:", self.internetEthernetAvailable)

                let internetWifiChanged = internetWifiAvailableOld != self.internetWifiAvailable
                let internetCellularChanged = internetCellularAvailableOld != self.internetCellularAvailable
                let internetEthernetChanged = internetEthernetAvailableOld != self.internetEthernetAvailable

In the past I had used Reachability, but no sane person can make sense of the code later on (even the author!). This PathMonitor seemed like a godsend! What I expected to see was changes to multiple interfaces going on:

cell -> satisfied: block gets called
wifi -> satisfied: block gets called
cell -> unsatisfied: block gets called

etc.

But that doesn't happen - I get notified when a path is available, so in the 3 events above I get the first two, but not the 3rd - I don't get "unsatisfied" if there is a path. I recall that if both are unavailable (AirPlane mode), at least the last "satisfied".

Perhaps I should have multiple monitors going - one for each of cell, wifi, and wired. Even then I'm skeptical of whether I'll get told when one goes down, but maybe that is unwarranted.


I know of all the arguments against doing this, and we should just kick off the network no matter. The reality is that the designers of the app I use have you go down a deep hole to do something if it's up, and if network is unreachable it doesn't even try. Just ignoring status at the moment would wreck havoc with the user base.

Because we allow massive data to flow in either direction, we also condition on cellular - but I believe most users don't disable cellular data, so its not been an issue (in the past they might have).

My recollection is that I could maintain separate states for cell, wifi, and wired using Reachability. If I have three NSPathMonitors for each, will I then get a real status for each?

Thanks!!!

Because we allow massive data to flow in either direction, we also condition on cellular

This results in a TOCTTOU window, which is one of the specific reasons why we recommend against using preflighting. A better approach is to apply constraints to your requests. That way they’ll never go over the wrong interface.

Also, we recommend against using Wi-Fi / WWAN for this, but rather use the expensive / inexpensive constraint. Without that, a user on truly unlimited WWAN will not be artificially constrained. Indeed, many such users are never on Wi-Fi.

We have a techtalk, Adapt to changing network conditions, that goes into this stuff in depth.

Share and Enjoy

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

NWPathMonitor.pathUpdateHandler behavior
 
 
Q