Swift
Internet Connection
Programming
Networking
iOS Development

Check for internet connection with Swift

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Checking for an internet connection in Swift sounds simple, but there are really two different questions. One is whether the device currently has a usable network path. The other is whether your actual backend or website is reachable. NWPathMonitor answers the first question well; a real request answers the second.

Use NWPathMonitor for Reachability State

Apple's modern reachability tool is NWPathMonitor from the Network framework. It tells you whether the system currently sees a satisfied path and whether that path uses Wi-Fi, cellular, or another interface.

swift
1import Foundation
2import Network
3
4final class ConnectivityMonitor {
5    private let monitor = NWPathMonitor()
6    private let queue = DispatchQueue(label: "ConnectivityMonitor")
7
8    private(set) var isConnected = false
9
10    func start() {
11        monitor.pathUpdateHandler = { [weak self] path in
12            self?.isConnected = path.status == .satisfied
13            print("Connected: \(path.status == .satisfied)")
14            print("Using Wi-Fi: \(path.usesInterfaceType(.wifi))")
15            print("Using Cellular: \(path.usesInterfaceType(.cellular))")
16        }
17        monitor.start(queue: queue)
18    }
19
20    func stop() {
21        monitor.cancel()
22    }
23}

That is the right building block for updating UI state, disabling network-dependent actions, or explaining to the user that the device currently has no route to the network.

Reachability Is Not the Same as Real Internet Access

A satisfied path does not guarantee your app can talk to the service it needs. The device may be on a captive portal, a misconfigured Wi-Fi network, or a filtered corporate network.

If your real question is "can I reach my API right now," make a small request to a health endpoint:

swift
1import Foundation
2
3func probeBackend() async -> Bool {
4    guard let url = URL(string: "https://example.com/health") else {
5        return false
6    }
7
8    var request = URLRequest(url: url)
9    request.httpMethod = "GET"
10    request.timeoutInterval = 5
11
12    do {
13        let (_, response) = try await URLSession.shared.data(for: request)
14        guard let httpResponse = response as? HTTPURLResponse else {
15            return false
16        }
17        return (200...299).contains(httpResponse.statusCode)
18    } catch {
19        return false
20    }
21}

That second check is what proves your service is reachable, not just that some network path exists.

A Good App Usually Uses Both

In practice, many apps combine both techniques:

  • 'NWPathMonitor updates general connectivity state'
  • a real request confirms service availability when needed

That separation keeps the app honest. It prevents you from showing a misleading "online" badge when the device has a path but your backend is down.

Avoid the Old Synchronous Habit

Older iOS code often tried to do a one-off synchronous reachability check before every request. That pattern leads to brittle logic. A better approach is:

  • observe path changes continuously
  • keep networking code resilient to request failures
  • handle real request errors even when reachability says a path exists

The network can always change between the check and the request anyway, so the request path still needs proper error handling.

Common Pitfalls

  • Treating NWPathMonitor as proof that your API is reachable.
  • Running a one-time connectivity check and assuming it stays valid.
  • Forgetting to keep a strong reference to the monitor so it continues running.
  • Updating UI directly from the monitor's background queue instead of dispatching to the main queue when needed.
  • Building logic that skips real error handling because a reachability check passed earlier.

Summary

  • Use NWPathMonitor to learn whether the device currently has a usable network path.
  • Use a real URLSession request to confirm that your backend is reachable.
  • Reachability and service availability are related but different checks.
  • Keep the monitor alive and handle updates on the correct queue.
  • Even with reachability monitoring, actual requests still need robust error handling.

Course illustration
Course illustration

All Rights Reserved.