How to check for network connection in SwiftUI using NWPathMonitor

Nikola Grujic
2 min readSep 24, 2023

NetworkMonitor

In order to check for any changes in the network connectivity, NWPathMonitor class can be used. It is provided by Apple as a part of Network framework.

With the introduction of @Observable macro in Swift 5.9, NetworkMonitor class can be implemented using the following code:

import Foundation
import Network

@Observable
class NetworkMonitor {
private let networkMonitor = NWPathMonitor()
private let workerQueue = DispatchQueue(label: "Monitor")
var isConnected = false

init() {
networkMonitor.pathUpdateHandler = { path in
self.isConnected = path.status == .satisfied
}
networkMonitor.start(queue: workerQueue)
}
}

First property is an NWPathMonitor observer, second property is a DispatchQueue where the monitor does its work. Third property is a bool value which will be tracked in the view in order to react on the changes in network connectivity.

NWPathMonitor is initialized without parameters, which means it will observe all connection types (wifi, celullar, wired ethernet and other).

Network unavailable view

With iOS 17, a new view for empty state was introduced, ContentUnavailableView

This new view can be conveniently used to create a warning view for a network connection error.

import SwiftUI

struct NetworkUnavailableView: View {
var body: some View {
ContentUnavailableView(
"No Internet Connection",
systemImage: "wifi.exclamationmark",
description: Text("Please check your connection and try again.")
)
}
}

#Preview {
NetworkUnavailableView()
}
Network unavailable view

Update UI

In order to use NetworkMonitor and update the view, NetworkMonitor has to be instantiated as a @State. Changes in the connection will update the value of isConnected flag and update the view. It can be implemented using this code:

struct ContentView: View {
@State private var networkMonitor = NetworkMonitor()

var body: some View {
if networkMonitor.isConnected {
Text("Internet Connection available")
} else {
ContentUnavailableView(
"No Internet Connection",
systemImage: "wifi.exclamationmark",
description: Text("Please check your connection and try again.")
)
}
}
}

Alternatively, NetworkMonitor can be injected as an environment object and used across the app.

@main
struct MyApp: App {
@State private var networkMonitor = NetworkMonitor()

var body: some Scene {
WindowGroup {
ContentView()
.environmentObject(networkMonitor)
}
}
}

struct ContentView: View {
@Environment(NetworkMonitor.self) private var networkMonitor

var body: some View {
if networkMonitor.isConnected {
Text("Internet Connection available")
} else {
ContentUnavailableView(
"No Internet Connection",
systemImage: "wifi.exclamationmark",
description: Text("Please check your connection and try again.")
)
}
}
}

Testing

Network connection changes are not detected consistently in the Simulator, the suggestion is to perform testing on a real device.

Inspired by

--

--

Nikola Grujic

Software Developer | Frontend | Mobile (iOS) | Desktop (macOS) | Swift, Objective-C | LinkedIn: linkedin.com/in/nikola-grujic-735a7284/