Reachability — це бібліотека для iOS та macOS, побудована на фреймворку SystemConfiguration, яка дозволяє перевіряти доступність інтернет-з'єднання та відстежувати його зміни. Згідно з Документацією Apple Developer (2025), Reachability використовує SCNetworkReachability для асинхронного моніторингу мережі. Бібліотека Reachability тривалий час залишалася стандартом для iOS-проєктів до появи нативного NWPathMonitor.
Головне
Reachability — це прикладна бібліотека від Apple, яка демонструє використання фреймворку SystemConfiguration для моніторингу мережі. Вихідний код було опубліковано в Документації Apple Developer як приклад, але спільнота прийняла його як стандартний інструмент перевірки з'єднання в iOS-проєктах.
Бібліотека працює на основі SCNetworkReachability — C-функції з SystemConfiguration, яка оцінює досяжність віддаленого хоста або IP-адреси. Під час створення Reachability вказується або ім'я хоста (наприклад, google.com), або IP-адреса, і бібліотека асинхронно перевіряє, чи доступний цей хост через поточні мережеві інтерфейси пристрою.
Популярність Reachability пояснюється її простотою: достатньо створити екземпляр, підписатися на сповіщення через NotificationCenter та слухати kReachabilityChangedNotification. У відповідь застосунок отримує статус: NotReachable, ReachableViaWiFi або ReachableViaWWAN (стільникові дані).
Reachability вперше з'явилася в iPhone OS 2 (2008) разом із фреймворком SystemConfiguration. Протягом десяти років вона була єдиним нативним способом моніторингу мережі в iOS. З виходом iOS 12 та фреймворку Network Apple рекомендує NWPathMonitor як заміну, але Reachability все ще підтримується.
Багато сторонніх обгорток — AFNetworking, Alamofire, AshleyDodd/Reachability.swift — використовують внутрішній механізм SCNetworkReachability. Ці бібліотеки додають зручний Swift/Objective-C інтерфейс, мемоізацію статусу та thread-safe колбеки, зберігаючи ту саму основу SystemConfiguration.
Основний механізм Reachability — функція SCNetworkReachabilityCreateWithName, яка створює об'єкт відстеження для вказаного хоста. Потім викликається SCNetworkReachabilityGetFlags — синхронна перевірка, яка повертає бітову маску SCNetworkReachabilityFlags з поточним станом мережі.
Для асинхронного моніторингу використовується SCNetworkReachabilitySetCallback, яка реєструє C-функцію зворотного виклику. Колбек виконується на поточному RunLoop, коли стан досяжності хоста змінюється. Reachability обгортає цей C-колбек у метод Objective-C і надсилає сповіщення через 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 — бітова маска, яка кодує стан мережі. Прапорець kSCNetworkReachabilityFlagsReachable вказує, що хост досяжний. kSCNetworkReachabilityFlagsConnectionRequired — для з'єднання потрібно встановити зв'язок. Комбінація прапорців визначає, чи може застосунок надсилати дані.
Додаткові прапорці: kSCNetworkReachabilityFlagsIsWWAN — з'єднання через стільникову мережу (iOS), kSCNetworkReachabilityFlagsInterventionRequired — потрібне втручання користувача (наприклад, для VPN). Reachability враховує ці прапорці для визначення типу інтерфейсу.
Стандартний патерн використання Reachability у iOS-застосунку включає створення екземпляра, підписку на сповіщення та реакцію на зміну статусу. У прикладі нижче показано інтеграцію з NotificationCenter для оновлення інтерфейсу при зміні мережі.
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("Підключено через Wi-Fi")
case .cellular:
print("Підключено через стільниковий зв'язок")
case .unavailable:
print("Немає з'єднання")
}
}
}
}
Перед виконанням HTTP-запиту можна перевірити доступність мережі синхронно: reachability.connection != .unavailable. Це не гарантує успіх запиту (сервер може бути недоступний), але запобігає свідомо невдалим запитам і покращує UX — застосунок не показує спінер в офлайн-режимі.
Для більш точної перевірки комбінуйте Reachability із таймаутами URLSession. Якщо Reachability показує reachable, але запит не виконується за таймаут — ймовірна проблема на стороні сервера або каптивний портал. У такому випадку можна показати користувачеві повідомлення про недоступність сервера.
Reachability розрізняє три основні стани з'єднання: Wi-Fi, стільникові дані (WWAN) та недоступність. WWAN включає всі типи стільникового зв'язку — 2G, 3G, 4G/LTE, 5G. Бібліотека не надає деталізації всередині WWAN, тому для розрізнення 4G та 5G потрібен CoreTelephony.
| Стан | Прапорець SCNetwork | Опис |
|---|---|---|
| ReachableViaWiFi | Reachable + !IsWWAN | Підключення через Wi-Fi мережу з доступом до хоста |
| ReachableViaWWAN | Reachable + IsWWAN | Підключення через стільникову мережу (2G-5G) |
| NotReachable | !Reachable | Хост недоступний через будь-який інтерфейс |
| ConnectionRequired | Reachable + ConnectionRequired | Потрібне встановлення з'єднання (VPN, PPPoE) |
Reachability не розрізняє Ethernet, VPN-тунелі або мультишляхові з'єднання — всі не-WWAN інтерфейси класифікуються як Wi-Fi. Це обмеження пов'язане з архітектурою SystemConfiguration, яка не надає детальної інформації про мережеві інтерфейси за межами базової класифікації.
Для визначення конкретного типу стільникового зв'язку (4G vs 5G) потрібен CTTelephonyNetworkInfo з CoreTelephony. Комбінування Reachability з CoreTelephony дозволяє застосунку вибирати якість контенту: при 5G — стрімінг у 4K, при 4G/LTE — HD, при 3G — SD або лише аудіо.
Apple рекомендує замінювати Reachability на NWPathMonitor у всіх нових проєктах, починаючи з iOS 12. Основна причина — NWPathMonitor є частиною сучасного фреймворку Network, написаний на Swift, підтримує Combine та надає детальну інформацію про мережевий шлях без використання C-сумісності.
Процес міграції включає заміну SCNetworkReachability на NWPathMonitor, перехід з NotificationCenter на pathUpdateHandler замикання або Combine publisher. Алгоритм та логіка обробки статусу мережі залишаються тими ж — змінюється лише API моніторингу.
protocol NetworkMonitorProtocol {
var isReachable: Bool { get }
var connectionType: ConnectionType { get }
func startMonitoring()
func stopMonitoring()
}
enum ConnectionType {
case wifi, cellular, ethernet, unavailable
}
// Сучасна реалізація з використанням 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()
}
}
Для проєктів із базовою підтримкою iOS 12+ замінюйте Reachability на NWPathMonitor повністю. Для проєктів, що підтримують iOS 11, використовуйте умовну компіляцію #available(iOS 12, *) з NWPathMonitor та Reachability як fallback. Це дозволяє поступово мігрувати без втрати підтримки старих пристроїв.
Основна перевага міграції — деталізація мережевого шляху. NWPathMonitor повідомляє не просто «доступно/недоступно», але й тип кожного інтерфейсу, їх витрати, пріоритет, підтримку проксі та VPN. Це дає розробнику більше даних для адаптації поведінки застосунку під поточні мережеві умови.
Поширені запитання
Reachability на SCNetworkReachability доступна починаючи з iPhone OS 2 (iOS 2). Бібліотека працює на всіх версіях iOS, включаючи актуальні. Обмеження стосуються не версії ОС, а деталізації інформації — на старих версіях немає розрізнення 4G та 5G.
Reachability використовує SCNetworkReachability — системний сервіс, який оцінює досяжність хоста на рівні мережевого стеку, не надсилаючи пакети. Ping надсилає ICMP-пакети та споживає трафік, а також може блокуватися брандмауером. Reachability швидша та безпечніша для частої перевірки.
Так, Reachability працює в SwiftUI через ObservableObject або Combine. Обгорніть її в клас, підписаний на NotificationCenter, і опублікуйте статус через @Published. Для нових SwiftUI-проєктів рекомендуємо NWPathMonitor з Combine publisher для реактивного оновлення View.
Reachability перевіряє прапорець kSCNetworkReachabilityFlagsIsWWAN у бітовій масці SCNetworkReachabilityFlags. Якщо прапорець встановлено — з'єднання через стільникову мережу (WWAN), якщо ні та хост Reachable — через Wi-Fi. Це єдиний спосіб розрізнити типи без CoreTelephony.
SCNetworkReachability перевіряє досяжність хоста на мережевому рівні, але не гарантує роботу вищележачих протоколів. Можливі причини: каптивний портал, блокування DNS, проксі-сервер або фаєрвол. Reachability — перший фільтр, але не заміна реальному HTTP-запиту.
Підсумки
Ми розробимо мобільний застосунок під ключ
IT Sectr створює застосунки для iOS та Android для стартапів і бізнесу з 2017 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.
Читайте також