Detect Network Reachability and Connection Type in SwiftUI

DevTechie Inc
Jun 24

In today’s connected world, apps relie on networks more than ever. This also mean that having a check for connectivity becomes the most basic requirement for any connected app. Prior iOS 12, reachability was achieved with various means, one of the most used code was provided by Apple which can be found here: https://developer.apple.com/library/archive/samplecode/Reachability/Introduction/Intro.html#//apple_ref/doc/uid/DTS40007324

Starting iOS 12, Apple introduced Network framework, which provides NWPathMonitor to observer, monitor and react the network changes.

NWPathMonitor has pathUpdateHandler closure to notify the network changes. This closure returns a NWPath type which is an object that contains information about the properties of the network that a connection uses or that are available to the app.

More detail on NWPath can be found here: https://developer.apple.com/documentation/network/nwpath

Now is the time to code. We will start with a class which will provide us a way to publish connected state of network. We will also have a published property to indicate if cellular network is being used or not.

import Networkfinal class NetworkMonitor: ObservableObject {
    @Published private(set) var isConnected = false
    @Published private(set) var isCellular = false
    
    private let nwMonitor = NWPathMonitor()
    private let workerQueue = DispatchQueue.global()
    
    public func start() {
        nwMonitor.start(queue: workerQueue)
        nwMonitor.pathUpdateHandler = { [weak self] path in
            DispatchQueue.main.async {
                self?.isConnected = path.status == .satisfied
                self?.isCellular = path.usesInterfaceType(.cellular)
            }
        }
    }
    
    public func stop() {
        nwMonitor.cancel()
    }
}
Start and Stop functions can be called to start/stop the network monitoring.

Our view will have just a few elements that are self explanatory:

struct NetworkStatusCheck: View {
    
    @StateObject var nw = NetworkMonitor()
    
    var body: some View {
        VStack {
            Text("DevTechie")
                
            Image(systemName: nw.isConnected ? "wifi" : "wifi.slash")
            
            if nw.isCellular {
                Image(systemName: "candybarphone")
            }
                
        }
        .font(.largeTitle)
        .foregroundColor(.orange)
        .onAppear {
            nw.start()
        }
        .onDisappear {
            nw.stop()
        }
    }
}
Final output will look like this.

Note: you will need actual device to test the feature out as its kinda flaky on simulator 😳


With that we have reached the end of this article. Thank you once again for reading. Subscribe to our weekly newsletter at https://www.devtechie.com