Search code examples
iosswiftconnectivitynetwork-frameworknwpathmonitor

Why network status does not get updated in swift?


I am using the new "Network" library introduced in iOS 12, but I can't figure out why the network status does not get updated to .satisfied after user gets connected.

here is the code so far:

import Network

class MapViewController: UIViewController {

    let networkMonitor = NWPathMonitor()
    let queue = DispatchQueue(label: "NetworkMonitor")

    override func viewDidLoad() {
        super.viewDidLoad()

        // check for internet connection
        networkMonitor.pathUpdateHandler = { path in
            if path.status != .satisfied {

                // alert the user to check internet connection
                let alert = UIAlertController(title: "Internet Error", message: "Unable to connect. Please check your internet connection.", preferredStyle: .alert)
                alert.addAction(UIAlertAction(title: "Cancel", style: .default, handler: nil))
                alert.addAction(UIAlertAction(title: "Retry", style: .default, handler: { (action) in
                    // TODO: after retry should update status but its not updated
                    print("Status after retry: \(path.status)")
                }))
                self.present(alert, animated: true, completion: nil)
            } else {
                print(path.status)
            }
        }


        networkMonitor.start(queue: queue)
     }
}

To replicate the lost connection situation in simulator, I turn off wifi connection before the view loads, when the alert shows up, tap retry. Surprisingly Status after retry stays .unsatisfied. Why status does not get updated ?

The goal is to tap "Retry" and if user is still not connected keep showing the alert, when user gets connected and tap retry alert should be dismissed.

In order to have an easy network monitor setup you can check this tutorial: https://medium.com/@rwbutler/nwpathmonitor-the-new-reachability-de101a5a8835

Please note that I don't specify network type when instantiating NWPathMonitor(), therefore it detects all types of connections.


Solution

  • NWPath is a struct, so therefore it is immutable. It won't change within a given invocation of pathUpdateHandler.

    Once a network path becomes available you will get a subsequent invocation of pathUpdateHandler with an .satisfied status.

    From a user-experience point of view it probably isn't a great approach to show a modal alert. You would typically indicate that the network connection is unavailable using some other indicator - a toast or icon - that disappears or changes once the network is available.

    Alternatively or additionally use .waitsForConnectivity on your connection.