How to Check Network Connection in SwiftUI Using NWPathMonitor

Husnain Ali
4 min readJul 8, 2024

--

In this article, I’ll explore how to monitor network connectivity in SwiftUI applications using NWPathMonitor.

Understanding the network status of your app is crucial for providing a seamless user experience, especially when dealing with data fetching or online services. I’ll explore setting up NWPathMonitor, integrating it with SwiftUI, and handling network changes effectively to ensure your app can respond dynamically to connectivity issues.

what is NWPathMonitor?

NWPathMonitor is a class within Apple’s Network framework designed to monitor the status of the network path. It helps in determining the availability of a network connection, the type of network connection (Wi-Fi, cellular, etc.), and other network characteristics. This is particularly useful for apps that need to handle network changes gracefully, such as switching from Wi-Fi to cellular or handling offline scenarios.

Key Features:

  1. Real-time Monitoring: NWPathMonitor provides real-time updates about network status changes.
  2. Network Type Detection: It can detect different network types, such as Wi-Fi, cellular, and Ethernet.
  3. Connection Quality Assessment: It helps in assessing the quality and reliability of the current network connection.
  4. IPv4/IPv6 Support: It supports both IPv4 and IPv6 connections.

Use Cases:

  • Handling Network Changes: Reacting to changes in network connectivity, such as switching from Wi-Fi to cellular data.
  • Offline Mode: Providing an offline mode when no network connection is available.
  • Optimizing Network Usage: Adjusting app behavior based on network quality, such as reducing data usage on a poor connection.

Example Usage:

Using NWPathMonitor involves creating an instance of the monitor, starting it, and handling the network path updates. Here’s a basic example:

import Network

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

monitor.pathUpdateHandler = { path in
if path.status == .satisfied {
print("We're connected!")
} else {
print("No connection.")
}

print(path.isExpensive)
}

monitor.start(queue: queue)

In this example, path.status is checked to determine if the network is available, and path.isExpensive indicates if the connection is via a cellular network.

NetworkMonitor

In this section, I’ll explore how to implement network reachability in SwiftUI using NWPathMonitor. We’ll create a protocol to define our reachability use case, and then build a concrete implementation of this protocol with a network monitor.

Define the Reachability Protocol

First, i will define a protocol ReachabilityUC which includes a single method execute that returns a Boolean indicating the network status.

protocol ReachabilityUC {
func execute() -> Bool
}

This protocol acts as a contract, ensuring that any class conforming to it will provide a method to check network connectivity.

Implement the Network Monitor Class

Next, i will create a class NetworkMonitor that conforms to the ReachabilityUC protocol. This class uses NWPathMonitor to monitor the network status.

class NetworkMonitor: ReachabilityUC {

private let monitor: NWPathMonitor
private let queue: DispatchQueue
private var isConnected = false

init() {
monitor = NWPathMonitor()
queue = DispatchQueue.global(qos: .background)
monitor.pathUpdateHandler = { [weak self] path in
self?.isConnected = path.status == .satisfied
}
monitor.start(queue: self.queue)
}

func execute() -> Bool {
isConnected
}
}

Key Components:
Properties:
monitor: An instance of NWPathMonitor used to monitor the network status.
queue: A background DispatchQueue where the network monitoring will take place.
isConnected: A Boolean variable to store the current network status.

Initializer:
init(): Initializes the NWPathMonitor and starts monitoring on a background queue. The pathUpdateHandler is used to update the isConnected variable based on the network status.

Method:
execute() -> Bool: Returns the current network status stored in the isConnected variable.

How It Works

Initialization: When an instance of NetworkMonitor is created, it initializes NWPathMonitor and starts monitoring network changes on a background queue.

let networkMonitor: ReachabilityUC

init(networkMonitor: ReachabilityUC) {
self.networkMonitor = networkMonitor
}

Monitoring Network Status: The pathUpdateHandler closure is called whenever there is a change in the network status. Inside this closure, we update the isConnected property based on whether the network status is .satisfied (indicating that there is a network connection).

networkMonitor.execute()

Checking Network Status: The execute method simply returns the value of isConnected, providing a way to check the network status at any point in time.

struct NetworkMonitorView: View {

@State private var isConnected = false

let networkMonitor: ReachabilityUC

init(networkMonitor: ReachabilityUC) {
self.networkMonitor = networkMonitor
}

var body: some View {
VStack {
Spacer()

if isConnected {
Image(systemName: "globe")
.imageScale(.large)
.foregroundStyle(.tint)
Text("Hello, world!")
} else {
NetworkUnavailableView()
}

Spacer()

Button {
isConnected = networkMonitor.execute()
} label: {
Text("Check for internet")
.foregroundColor(.black)
}
}
.onAppear {
isConnected = networkMonitor.execute()
}
.padding()
}
}

#Preview {
NetworkMonitorView(networkMonitor: NetworkMonitor())
}

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.

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()
}

Monitoring network connectivity is crucial for ensuring a seamless user experience in any application. By using NWPathMonitor within the Network framework, we can efficiently track network status changes in our SwiftUI applications. In this article, we’ve demonstrated how to implement a protocol-based approach for network reachability, leveraging NWPathMonitor to keep our app responsive to connectivity changes.

This implementation provides a robust solution for checking network status, allowing developers to create more resilient and user-friendly applications.

For a complete implementation and to see the code in action, visit my GitHub repository: NetworkMonitor on GitHub. You’ll find the full source code and examples of how to integrate network monitoring into your SwiftUI projects.

Visit the Repository

You can view and clone the full implementation of the network monitor from my GitHub repository:

NetworkMonitor on GitHub

Feel free to explore, use, and modify the code to fit your needs. Contributions and feedback are always welcome!

--

--

Husnain Ali

A Lead iOS Engineer at ILI.DIGITAL AG. Follow me for a dose of practical swift knowledge! Let's explore the iOS ecosystem together. 🚀💻