Why NWPath.status always return "unsatisfied" on my iPhone

Hi! I am trying to use the NWPathMonitor to check the network connectivity on my iPhone. However the NWPath object from the monitor is always has status property being "unsatisfied" regardless whether I turn the wifi and cell data on or off. Below is the simple code I tried. For simplicity I make the requiredInterfaceType be just WIFI. However, does matter whether I turn WIFI on or off, the label display is always "Unsatifsfied"


Can you help me to find whey?


Thank you!


class ViewController: UIViewController {
    var mon: NWPathMonitor = NWPathMonitor(requiredInterfaceType: .wifi)
    @IBOutlet weak var statusLabel: UILabel!
    
    override func viewDidLoad() {
        super.viewDidLoad()
    }

    @IBAction func detect(_ sender: Any) {
        let cp : NWPath = mon.currentPath
        if cp.status == .satisfied {
            statusLabel.text = "Satisfied"
        } else if cp.status == .requiresConnection {
            statusLabel.text = "Requires Connection"
        } else if cp.status == .unsatisfied {
            statusLabel.text = "Unsatisfied"
        } else {
            statusLabel.text = "Unknown"
        }
    }
}
Answered by DTS Engineer in 388676022
NWPathMonitor
is, as the name suggests, meant to monitor a network path. It won’t do anything useful if you just create it and read then read the status. You need to set a path update handler on it (
pathUpdateHandler
) and then start it (
start(queue:)
).

Share and Enjoy
—
Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"
Accepted Answer
NWPathMonitor
is, as the name suggests, meant to monitor a network path. It won’t do anything useful if you just create it and read then read the status. You need to set a path update handler on it (
pathUpdateHandler
) and then start it (
start(queue:)
).

Share and Enjoy
—
Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Hi eskimo,


Thank you! After defining a handler function and calling the start(queue) method, the monitor works for me. On another hand I found that the handler cannot directly change the UI in main thread, because it is already in another thread. I added some more change to do the UI label change. I don't use a button action to check the status anymore. The new code is like below.


class ViewController: UIViewController {
    var mon: NWPathMonitor = NWPathMonitor()
    var queue = DispatchQueue(label: "Monitor")
    
    @IBOutlet weak var statusLabel: UILabel!
    
    override func viewDidLoad() {
        super.viewDidLoad()
    }
    
    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        
        mon.pathUpdateHandler = {
            p in
            if p.status == .satisfied {
                DispatchQueue.main.async {
                    self.statusLabel.text = "Satisfied"
                }
            } else if p.status == .requiresConnection {
                DispatchQueue.main.async {
                    self.statusLabel.text = "Requires Connection"
                }
            } else if p.status == .unsatisfied {
                DispatchQueue.main.async {
                    self.statusLabel.text = "Unsatisfied"
                }
            } else {
                DispatchQueue.main.async {
                    self.statusLabel.text = "Unknown"
                }
            }
        }
        mon.start(queue: queue)
    }
}