Reachability — библиотека за iOS и macOS, изградена върху рамката SystemConfiguration, която позволява да проверявате наличността на интернет връзката и да проследявате нейните промени. Според Apple Developer Documentation (2025), Reachability използва SCNetworkReachability за асинхронно мониторинг на мрежата. Библиотеката Reachability дълго време остава стандарт за iOS проекти до появата на родния NWPathMonitor.
Основни поенти
Reachability — е примерна библиотека от Apple, която демонстрира използването на рамката SystemConfiguration за мониторинг на мрежата. Изходният код е публикуван в Apple Developer Documentation като пример, но общността го е приела като стандартен инструмент за проверка на връзката в iOS проекти.
Библиотеката работи на базата на SCNetworkReachability — C функция от SystemConfiguration, която оценява достижимостта на отдалечен хост или IP адрес. При създаването на Reachability се посочва или име на хост (u043fр. 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 — изисква намеса от потребител (u043fр. за VPN). Reachability взема предвид тези флагове за определяне на типа на интерфейса.
Стандартният модел за използване на Reachability в iOS приложение включва създаване на инстанция, абониране за известия и реакция на промяна на статуса. Примерът по-долу показва интеграцията с NotificationCenter за актуализиране на UI при промяна на мрежата.
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 — приложението не показва spinner в офлайн режим.
За по-точна проверка, комбинирайте Reachability с URLSession таймаути. Ако Reachability показва reachable, но заявката не се изпълнява в рамките на таймаута — проблемът е вероятно от страна на сървъра или captive portal. В този случай можете да покажете на потребителя съобщение за недостъпността на сървъра.
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 тунели или multipath връзки — всички не-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 closure или 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 не само отчита „достъпен/недостъпен”, но също типа на всеки интерфейс, неговите разходи, приоритет, поддръжка на proxy и VPN. Това дава на разработчика повече данни за адаптиране на поведението на приложението към текущите мрежови условия.
Често задавани въпроси
Reachability на SCNetworkReachability е достъпна от iPhone OS 2 (iOS 2). Библиотеката работи на всички версии на iOS, включително текущите. Ограниченията не се отнасят до версията на OS, а до подробността на информацията — на старите версии няма разлика между 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 проверява достижимостта на хоста на мрежово ниво, но не гарантира работата на протоколите от по-високо ниво. Възможни причини: captive portal, DNS блокиране, proxy сървър или брандмауер. Reachability е първият филтър, но не заменя истинската HTTP заявка.
Обобщение
Ще разработим мобилно приложение под ключ
IT Sectr създава iOS и Android приложения за стартъпи и бизнеси от 2017 г. Ще ви консултираме и ще предложим най-доброто решение.
Прочетете също