How to Check Network Connection in SwiftUI Using NWPathMonitor
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:
- Real-time Monitoring: NWPathMonitor provides real-time updates about network status changes.
- Network Type Detection: It can detect different network types, such as Wi-Fi, cellular, and Ethernet.
- Connection Quality Assessment: It helps in assessing the quality and reliability of the current network connection.
- 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:
Feel free to explore, use, and modify the code to fit your needs. Contributions and feedback are always welcome!