Search code examples
swiftmacosconnectivitynwpathmonitor

NWPathMonitor does not respond to Network Link Conditioner profile changes


I am developing a macOS app and want to check connectivity status. I've created a simple connectivity observer using NWPathMonitor; I use it as en environment object:

@Observable
class ConnectivityMonitor {
    private let queue = DispatchQueue(label: "ConnectivityMonitorQueue")
    private let monitor = NWPathMonitor()
    
    private(set) var isConnected: Bool = false
    
    init() {
        monitor.pathUpdateHandler = { [weak self] path in
            DispatchQueue.main.async {
                self?.isConnected = path.status == .satisfied
                print("network path changed: ", path.status)
            }
        }
        monitor.start(queue: queue)
    }
}

To check different connectivity statuses, I use Network Link Conditioner prefpane (I will call it NLC) provided with Xcode Additional Tools by Apple.

I don't know why but NWPathMonitor does not respond to NLC profile changes.

For example; I set NLC profile to 100% Loss which means there is no internet connection on the network at all. But NWPathMonitor's pathUpdateHandler is not called.

Do I miss something? Thank you.


Solution

  • 100% loss is not the same as disconnected. NWPathMonitor is checking for the existence of a route. By a route I mean there is a local network interface that will accept packets destined for the given address.

    That route exists. It happens to drop every packet, but the monitor doesn't know that and can't know that. The only way to know whether a packet will be delivered is to send a packet and receive a response. NWPathMonitor doesn't send any packets at all, so it can't see packet loss.

    NLC also, by design, does not modify the network configuration for 100% packet loss. Testing this common situation (connected, but not delivering packets) is extremely useful and difficult to do otherwise. Testing "truly disconnected" is easy: turn off your network. But simulating networks that do not connect to the internet (for example, in airports or other businesses that offer wifi) is an ideal use case for NLC.

    As a rule, "reachability" checks are of limited use. They can tell you that the system won't even try to send a packet because the radio is turned off, and they're particularly good at telling you when it might be worth re-trying a failed connection. But they can't tell you that messages you send will actually be delivered. In the end, you have to send the packet and see what happens.

    This isn't a failing of NWPathMonitor. It's a basic fact about networks. They're like the Post Office. There's no way to know that a letter you put in your mailbox will actually be delivered, and if it is, whether the other party will respond. NWPathMonitor is telling you "yep, there's a mailbox on the corner and it's not locked." If your postal carrier decided to dump all the letters in a ditch (100% packet loss), there's no way to know that ahead of time.