Native approach to monitor network reachability on iOS

The Blue Prototype
3 min readDec 5, 2020

--

instagram.com/the_lens_on

There are lots of third party libraries to monitor the network reachability on iOS e.g. ReachabilitySwift, Alamofire etc. All these libraries provide an easy way to integrate in the code. Considering that all of you are already aware of them.

Get Started

Apple has released a new Network.framework in iOS 12. There are lots of apis to deal with the network on iOS. We can check network status and can do network monitoring also by Network.framework.

Apple Network Framework

In this article, I’ll explain that how can I create a network reachability protocol which will monitor network and check network current status. Before that, let’s discuss some apis which will be used to achieve this requirement.

NWPath

An object that contains information about the properties of the network that a connection uses, or that are available to your app.

NWPathMonitor

An observer that you use to monitor and react to network changes.

NWInterface

An interface that a network connection uses to send and receive data.

Let’s start code

Firstly, I created a protocol ‘NetworkReachabilityProtocol’ of AnyObject type.

protocol NetworkReachabilityProtocol: AnyObject {     var networkPathMonitor: NetworkPathMonitor? { get set }     func networkStatusChanged(isConnected: Bool)     // To check network status     func isNetworkAvailable() -> Bool     // Start & Stop network monitoring     func startNetworkMonitoring()     func stopNetworkMonitoring()}

In this protocol, I have one property ‘networkPathMonitor’ of ‘NetworkPathMonitor’ type, where ‘NetworkPathMonitor’ is the typealias name ofNWPathMonitor’.

typealias NetworkPathMonitor = NWPathMonitor

Second is a function ‘networkStatusChanged()’ which will notify me when there is any update in the network status.

Third is the ‘isNetworkAvailable()’ function to check the current network’s status.

And in the last, I have 2 functions to start & stop the network’s montoring — ‘startNetworkMonitoring()’ and ‘stopNetworkMonitoring()’.

Protocol functions definitions:

extension NetworkReachabilityProtocol {   func isNetworkAvailable() -> Bool {      if self.networkPathMonitor?.currentPath.status == .satisfied {         return true      } else {         return false      }   }}

In the above code, I just created the extension of ‘NetworkReachabilityProtocol’ protocol and write ‘isNetworkAvailable()’ function’s definition to get the current network status by the help of current path of network path monitor object.

extension NetworkReachabilityProtocol {   func startNetworkMonitoring() {      if self.networkPathMonitor == nil {         self.networkPathMonitor = NWPathMonitor()      }      let queue = DispatchQueue(label: "NetworkMonitoring")      self.networkPathMonitor?.pathUpdateHandler = { [weak self] (path) in        if self?.networkPathMonitor?.currentPath.status == .satisfied {           self?.networkStatusChanged(isConnected: true)        } else {           self?.networkStatusChanged(isConnected: false)        }    }    self.networkPathMonitor?.start(queue: queue)  }}

In the definition of ‘startNetworkMonitoring()’ function, created network path monitor object if it is not created. Then, on a different thread, using the pathUpdateHandler closure to get callback whenever there is any change in the network and calling back the ‘networkStatusChanged’ function with current status. After that, started the network monitoring.

extension NetworkReachabilityProtocol {   func stopNetworkMonitoring() {      self.networkPathMonitor?.cancel()      self.networkPathMonitor = nil   }}

In the ‘stopNetworkMonitoring()’ function, Cancelled the network monitoring and deintialize the ‘networkPathMonitor’ object.

Use ‘NetworkReachabilityProtocol’ in UIViewController ✍️

class ViewController: UIViewController, NetworkReachabilityProtocol {   var networkPathMonitor: NetworkPathMonitor?   func networkStatusChanged(isConnected: Bool) {      print("networkStatusChanged called - \(isConnected)")   }   override func viewDidLoad() {      super.viewDidLoad()
self.startNetworkMonitoring()
} deinit { self.stopNetworkMonitoring() } @IBAction func checkNetworkStatus(_ sender: UIButton) { if self.isNetworkAvailable() { print("===== Network is Available =====") } else { print("===== Network is Not Available =====") } }}

Here, You can see that I confirmed the protocol. In the ‘viewDidLoad’ life cycle method, I started the network monitoring and in the ‘networkStatusChanged’ method, you’ll receive network change callback everytime. Stopped the network monitoring in the ‘deinit’ method. I am also checking the status on a button action ‘checkNetworkStatus’. 👌

Summary

Protocols are the strong point in the swift programming language. So I focused on protocol oriented approach. But same thing we can achieve by singleton approach. Easy to integrate this protocol in any class. Enjoy the code.

Here is link of full source code: https://github.com/sanjeevworkstation/NetworkReachabilityByFramework

Thank You. Happy coding! 👍

You love photography? Checkout Instagram page: @the_lens_on

--

--