With iOS 12, Apple has introduced Network, a framework that includes the NWPathMonitor class. NWPathMonitor gives us the means to monitor changes of state in the internet connection. If you ever used Apple’s older Reachability (prior to iOS 12) system, NWPathMonitor replaces it fully.
NWPathMonitor
To use this new way to check the status of the internet connection, we first need to create an instance of NWPathMonitor:
let monitor = NWPathMonitor()
We can also instantiate the NWPathMonitor class indicating a particular type of network that we want to check. For example, to check WiFi connections:
let monitor = NWPathMonitor(requiredInterfaceType: .wifi)
NWPathMonitor can check different types of interfaces:
cellular for 3G / 4G connectionsloopback for localhostother for virtual networks or unknown network typeswifi for WiFi connectionswiredEthernet. If the device is connected to the internet by cable.Detection of changes in the state of the internet connection are made through the pathUpdateHandler property:
monitor.pathUpdateHandler = { path in
if path.status == .satisfied {
print("There is internet")
} else {
print("No internet")
}
}
NWPath has a few properties, but there are two in particular you’re likely to care about: status describes whether the connection is currently available or not, and isExpensive is set to true when using cellular data or when using WiFi that is hotspot routed through an iPhone’s cellular connection.
unsatisfied. The connection (path) cannot be used.satisfied. The connection (path) has been established and allows data to be sent.requiresConnection. The connection (path) is not currently available, but if a new connection is established it can be activated.In order to start receiving information about changes in the state of the internet connection, we need to call the start() method. The start() method needs a queue to do this job:
let queue = DispatchQueue(label: "Monitor") monitor.start(queue: queue)
Once we no longer need to know the changes in the state of the internet connection, we will call the cancel() method.
Let's write Singleton class to collect information about network status
import Network
public enum ConnectionType {
case wifi
case ethernet
case cellular
case unknown
}
class NetworkStatus {
static public let shared = NetworkStatus()
private var monitor: NWPathMonitor
private var queue = DispatchQueue.global()
var isOn: Bool = true
var connType: ConnectionType = .wifi
val listener: () -> Void
private init() {
self.monitor = NWPathMonitor()
self.queue = DispatchQueue.global(qos: .background)
self.monitor.start(queue: queue)
}
func start() {
self.monitor.pathUpdateHandler = { path in
self.isOn = path.status == .satisfied
self.connType = self.checkConnectionTypeForPath(path)
}
}
func stop() {
self.monitor.cancel()
}
func checkConnectionTypeForPath(_ path: NWPath) -> ConnectionType {
if path.usesInterfaceType(.wifi) {
return .wifi
} else if path.usesInterfaceType(.wiredEthernet) {
return .ethernet
} else if path.usesInterfaceType(.cellular) {
return .cellular
}
return .unknown
}
}
Example of usage
let net = NetworkStatus.shared net.start() // Internet connection monitoring starts net.cancel() // Internet connection monitoring stops let status = net.connType // Returns the connection type
Reachability
If your app supports iOS versions before iOS 12, you’ll want to use the older Reachability component. It uses the SCNetworkReachability class to create a network socket, and to listen for changes.
We can use Reachability as follows. First, we’ll create a closure like this:
let onUpdate = { reachability in
if reachability.connection == .wifi {
print("We have WiFi!")
} else if reachability.connection == .cellular {
print("We have 3G/4G!")
} else {
print("No internet :-(")
}
}
Then, we’re creating a Reachability object and assign the onUpdate closure to two of its properties:
let reachability = Reachability() reachability?.whenReachable = onUpdate reachability?.whenUnreachable = onUpdate
The closure we defined earlier is now called whenever the network connectivity status changes.
Finally, we need to start the reachability component to get connectivity updates. Here’s how:
do {
try reachability.startNotifier()
} else {
print("Error starting Reachability...")
}