Reachability in Swift

March 4, 2018 Reacting to network reachability changes through a clean API.

In this post, I would like to share my implementation of a simple network reachability service that provides current state and posts notifications when network conditions change—without the need for a third-party library.

Usage

To get started, just copy the file below into your project and you are ready to go!

There is an easy-to-access Reachability.shared that you should prefer over creating your own instances—doing this for every cell in a table view is not a good idea performance-wise.

When initializing a custom instance, you can also provide a custom host to try to connect to. Your application will crash with a fatal error if this host name is invalid.

Inquiring Network Status

Checking for network connectivity is as easy as:

Reachability.shared.currentFlags.contains(.reachable)

Want to know whether the device is on mobile data?

Reachability.shared.currentFlags.contains(.isWWAN)

To make sure the reachability flags are up-to-date, call Reachability.shared.update().

Getting Notified About Changes

First things first: Activate the shared reachability service (e.g. in your AppDelegate) so it will start watching for changes.

Reachability.shared.isActive = true

Now, it will post an reachabilityDidChange notification on every change. It also passes along the new reachability flags. Plus, no need to call update() anymore!

Anywhere where you need it, you can observe these notifications on NotificationCenter.default as follows:

NotificationCenter.default.addObserver(forName: .reachabilityDidChange, object: nil, queue: .main) { notification in
    print(notification.userInfo?[Notification.Name.reachabilityDidChangeFlagsKey])
}

All notifications will be posted on the main queue.

Don’t forget to remove your observer if it is no longer needed!

How It Works

Basically, this class is just a wrapper around SCNetworkReachability, which is a C-API contained in SystemConfiguration. On initialization, it creates a reachability reference to a network host and determines whether or under what conditions it is reachable.

The change watcher also takes advantage of this API. However, there are some restrictions on callback closures as they need to be compatible with C function pointers. This is why you cannot access self inside the closure but instead need to wrap a reference tp it inside an opaque reference, which is then passed along and eventually unwrapped in the callback. After that, the process is really straightforward: Make sure the flags actually changed, update the current flags, and post a notification if needed.

Code