Reachability — biblioteka dla systemów iOS i macOS, zbudowana na frameworku SystemConfiguration, która umożliwia sprawdzanie dostępności połączenia internetowego i śledzenie jego zmian. Według Apple Developer Documentation (2025), Reachability używa SCNetworkReachability do asynchronicznego monitorowania sieci. Biblioteka Reachability przez długi czas pozostawała standardem dla projektów iOS aż do pojawienia się natywnego NWPathMonitor.
Najważniejsze
Reachability — to przykładowa biblioteka od Apple, demonstrująca użycie frameworku SystemConfiguration do monitorowania sieci. Kod źródłowy został opublikowany w Apple Developer Documentation jako przykład, ale społeczność przyjęła go jako standardowe narzędzie do sprawdzania połączenia w projektach iOS.
Biblioteka działa na podstawie SCNetworkReachability — funkcji C z SystemConfiguration, która ocenia osiągalność zdalnego hosta lub adresu IP. Podczas tworzenia Reachability podaje się either nazwę hosta (np. google.com) albo adres IP, a biblioteka asynchronicznie sprawdza, czy ten host jest dostępny przez bieżące interfejsy sieciowe urządzenia.
Popularność Reachability wynika z jej prostoty: wystarczy utworzyć instancję, zasubskrybować powiadomienia przez NotificationCenter i nasłuchiwać kReachabilityChangedNotification. W odpowiedzi aplikacja otrzymuje status: NotReachable, ReachableViaWiFi lub ReachableViaWWAN (dane komórkowe).
Reachability pojawiła się po raz pierwszy w iPhone OS 2 (2008) wraz z frameworkiem SystemConfiguration. Przez dziesięć lat była jedynym natywnym sposobem monitorowania sieci w iOS. Wraz z wydaniem iOS 12 i frameworku Network Apple zaleca NWPathMonitor jako zamiennik, ale Reachability wciąż jest wspierana.
Wiele zewnętrznych nakładek — AFNetworking, Alamofire, AshleyDodd/Reachability.swift — używa wewnętrznego mechanizmu SCNetworkReachability. Te biblioteki dodają wygodny interfejs Swift/Objective-C, memoizację statusu i thread-safe callbacki, zachowując tę samą podstawę SystemConfiguration.
Główny mechanizm Reachability — funkcja SCNetworkReachabilityCreateWithName, która tworzy obiekt śledzenia dla określonego hosta. Następnie wywoływana jest SCNetworkReachabilityGetFlags — synchroniczne sprawdzenie, zwracające maskę bitową SCNetworkReachabilityFlags z bieżącym stanem sieci.
Do asynchronicznego monitorowania używana jest SCNetworkReachabilitySetCallback, rejestrująca funkcję zwrotną w C. Callback jest wykonywany na bieżącym RunLoop, gdy zmienia się stan osiągalności hosta. Reachability opakowuje ten C-callback w metodę Objective-C i wysyła powiadomienie przez NotificationCenter.
import SystemConfiguration
class Reachability {
private var reachabilityRef: SCNetworkReachability?
init?(hostname: String) {
reachabilityRef = SCNetworkReachabilityCreateWithName(
nil, hostname
)
}
func checkReachability() -> Bool {
var flags = SCNetworkReachabilityFlags()
SCNetworkReachabilityGetFlags(
reachabilityRef!, &flags
)
return isReachable(with: flags)
}
private func isReachable(with flags: SCNetworkReachabilityFlags) -> Bool {
let reachable = flags.contains(.reachable)
let connectionRequired = flags.contains(.connectionRequired)
return reachable && !connectionRequired
}
}
SCNetworkReachabilityFlags — maska bitowa, która koduje stan sieci. Flaga kSCNetworkReachabilityFlagsReachable wskazuje, że host jest osiągalny. kSCNetworkReachabilityFlagsConnectionRequired — do połączenia wymagane jest nawiązanie łączności. Kombinacja flag określa, czy aplikacja może wysyłać dane.
Dodatkowe flagi: kSCNetworkReachabilityFlagsIsWWAN — połączenie przez sieć komórkową (iOS), kSCNetworkReachabilityFlagsInterventionRequired — wymagana interwencja użytkownika (np. dla VPN). Reachability uwzględnia te flagi do określenia typu interfejsu.
Standardowy wzorzec użycia Reachability w aplikacji iOS obejmuje utworzenie instancji, subskrypcję powiadomień i reakcję na zmianę statusu. Poniższy przykład pokazuje integrację z NotificationCenter do aktualizacji UI przy zmianie sieci.
import Reachability
import UIKit
class ViewController: UIViewController {
var reachability: Reachability?
override func viewDidLoad() {
super.viewDidLoad()
reachability = Reachability(hostname: "google.com")
NotificationCenter.default.addObserver(
self,
selector: #selector(reachabilityChanged),
name: .reachabilityChanged,
object: nil
)
reachability?.startNotifier()
}
@objc func reachabilityChanged(notification: Notification) {
if let reachability = notification.object as? Reachability {
switch reachability.connection {
case .wifi:
print("Połączono przez Wi-Fi")
case .cellular:
print("Połączono przez sieć komórkową")
case .unavailable:
print("Brak połączenia")
}
}
}
}
Przed wykonaniem zapytania HTTP można sprawdzić dostępność sieci synchronicznie: reachability.connection != .unavailable. Nie gwarantuje to sukcesu zapytania (serwer może być niedostępny), ale zapobiega z góry skazanym na niepowodzenie zapytaniom i poprawia UX — aplikacja nie pokazuje spinnera w trybie offline.
W celu dokładniejszego sprawdzenia łączcie Reachability z timeoutami URLSession. Jeśli Reachability pokazuje reachable, ale zapytanie nie wykonuje się w czasie timeoutu — prawdopodobnie problem leży po stronie serwera lub portal captive. W takim przypadku można wyświetlić użytkownikowi komunikat o niedostępności serwera.
Reachability rozróżnia trzy główne stany połączenia: Wi-Fi, dane komórkowe (WWAN) i brak dostępności. WWAN obejmuje wszystkie typy łączności komórkowej — 2G, 3G, 4G/LTE, 5G. Biblioteka nie zapewnia szczegółowości w ramach WWAN, dlatego do rozróżnienia 4G i 5G wymagany jest CoreTelephony.
| Stan | Flaga SCNetwork | Opis |
|---|---|---|
| ReachableViaWiFi | Reachable + !IsWWAN | Połączenie przez sieć Wi-Fi z dostępem do hosta |
| ReachableViaWWAN | Reachable + IsWWAN | Połączenie przez sieć komórkową (2G-5G) |
| NotReachable | !Reachable | Host niedostępny przez żaden interfejs |
| ConnectionRequired | Reachable + ConnectionRequired | Wymagane nawiązanie połączenia (VPN, PPPoE) |
Reachability nie rozróżnia Ethernetu, tuneli VPN ani połączeń multipath — wszystkie interfejsy nie-WWAN są klasyfikowane jako Wi-Fi. To ograniczenie wynika z architektury SystemConfiguration, która nie zapewnia szczegółowych informacji o interfejsach sieciowych poza podstawową klasyfikacją.
Do określenia konkretnego typu łączności komórkowej (4G vs 5G) wymagany jest CTTelephonyNetworkInfo z CoreTelephony. Połączenie Reachability z CoreTelephony pozwala aplikacji wybierać jakość treści: przy 5G — streaming w 4K, przy 4G/LTE — HD, przy 3G — SD lub tylko audio.
Apple zaleca zastąpienie Reachability przez NWPathMonitor we wszystkich nowych projektach, począwszy od iOS 12. Głównym powodem jest to, że NWPathMonitor jest częścią nowoczesnego frameworku Network, napisanego w Swift, obsługującego Combine i dostarczającego szczegółowych informacji o ścieżce sieciowej bez użycia zgodności z C.
Proces migracji obejmuje zastąpienie SCNetworkReachability przez NWPathMonitor, przejście z NotificationCenter na closure pathUpdateHandler lub publisher Combine. Algorytm i logika przetwarzania statusu sieci pozostają takie same — zmienia się tylko API monitorowania.
protocol NetworkMonitorProtocol {
var isReachable: Bool { get }
var connectionType: ConnectionType { get }
func startMonitoring()
func stopMonitoring()
}
enum ConnectionType {
case wifi, cellular, ethernet, unavailable
}
// Nowoczesna implementacja z użyciem NWPathMonitor
class ModernNetworkMonitor: NetworkMonitorProtocol {
private let monitor = NWPathMonitor()
private let queue = DispatchQueue("Network")
private var currentPath: NWPath?
var isReachable: Bool {
currentPath?.status == .satisfied
}
func startMonitoring() {
monitor.pathUpdateHandler = { [weak self] path in
self?.currentPath = path
}
monitor.start(on: queue)
}
func stopMonitoring() {
monitor.cancel()
}
}
W przypadku projektów z podstawowym wsparciem iOS 12+ zastąp Reachability całkowicie przez NWPathMonitor. W przypadku projektów obsługujących iOS 11 użyj kompilacji warunkowej #available(iOS 12, *) z NWPathMonitor i Reachability jako fallback. Pozwala to stopniowo migrować bez utraty wsparcia dla starszych urządzeń.
Główną zaletą migracji jest szczegółowość ścieżki sieciowej. NWPathMonitor informuje nie tylko „dostępny/niedostępny”, ale także typ każdego interfejsu, ich koszty, priorytet, obsługę proxy i VPN. Daje to deweloperowi więcej danych do dostosowania zachowania aplikacji do bieżących warunków sieciowych.
Często zadawane pytania
Reachability na SCNetworkReachability jest dostępna od iPhone OS 2 (iOS 2). Biblioteka działa na wszystkich wersjach iOS, włącznie z aktualnymi. Ograniczenia dotyczą nie wersji systemu, ale szczegółowości informacji — w starszych wersjach nie ma rozróżnienia 4G i 5G.
Reachability używa SCNetworkReachability — usługi systemowej, która ocenia osiągalność hosta na poziomie stosu sieciowego bez wysyłania pakietów. Ping wysyła pakiety ICMP i zużywa ruch, a także może być blokowany przez zaporę. Reachability jest szybsza i bezpieczniejsza do częstego sprawdzania.
Tak, Reachability działa w SwiftUI przez ObservableObject lub Combine. Opakuj ją w klasę subskrybującą NotificationCenter i opublikuj status przez @Published. Dla nowych projektów SwiftUI zalecamy NWPathMonitor z publisherem Combine do reaktywnej aktualizacji widoku.
Reachability sprawdza flagę kSCNetworkReachabilityFlagsIsWWAN w masce bitowej SCNetworkReachabilityFlags. Jeśli flaga jest ustawiona — połączenie przez sieć komórkową (WWAN), jeśli nie i host jest Reachable — przez Wi-Fi. Jest to jedyny sposób na rozróżnienie typów bez CoreTelephony.
SCNetworkReachability sprawdza osiągalność hosta na poziomie sieci, ale nie gwarantuje działania protokołów wyższego poziomu. Możliwe przyczyny: portal captive, blokada DNS, serwer proxy lub firewall. Reachability to pierwszy filtr, ale nie zastępuje rzeczywistego zapytania HTTP.
Podsumowanie
Opracujemy aplikację mobilną pod klucz
IT Sectr tworzy aplikacje na iOS i Androida dla startupów i firm od 2017 roku. Doradzimy Ci i zaproponujemy najlepsze rozwiązanie.
Przeczytaj również