Reachability는 SystemConfiguration 프레임워크 기반으로 구축된 iOS 및 macOS용 라이브러리로, 인터넷 연결 가용성을 확인하고 변경 사항을 추적할 수 있습니다. Apple Developer 문서(2025)에 따르면 Reachability는 비동기 네트워크 모니터링을 위해 SCNetworkReachability를 사용합니다. Reachability 라이브러리는 네이티브 NWPathMonitor가 등장하기 전까지 오랫동안 iOS 프로젝트의 표준으로 남아 있었습니다.
핵심 요점
Reachability는 네트워크 모니터링을 위한 SystemConfiguration 프레임워크 사용을 보여주는 Apple의 샘플 라이브러리입니다. 소스 코드는 Apple Developer 문서에 예제로 게시되었지만, 커뮤니티에서 iOS 프로젝트의 연결 확인 표준 도구로 채택했습니다.
라이브러리는 SCNetworkReachability — SystemConfiguration의 C 함수로, 원격 호스트 또는 IP 주소의 연결 가능성을 평가합니다 — 를 기반으로 합니다. Reachability를 생성할 때 호스트명(예: google.com) 또는 IP 주소를 지정하면 라이브러리가 비동기적으로 이 호스트가 기기의 현재 네트워크 인터페이스를 통해 연결 가능한지 확인합니다.
Reachability의 인기는 단순성에 있습니다: 인스턴스를 생성하고, NotificationCenter를 통해 알림을 구독하고, kReachabilityChangedNotification을 수신하면 됩니다. 응답으로 앱은 NotReachable, ReachableViaWiFi 또는 ReachableViaWWAN(셀룰러 데이터) 상태를 받습니다.
Reachability는 iPhone OS 2(2008)에서 SystemConfiguration 프레임워크와 함께 처음 등장했습니다. 10년 동안 iOS에서 네트워크 상태를 모니터링하는 유일한 네이티브 방법이었습니다. iOS 12 및 Network 프레임워크 출시와 함께 Apple은 NWPathMonitor를 대체품으로 권장하지만, Reachability는 여전히 지원됩니다.
많은 서드파티 래퍼 — AFNetworking, Alamofire, AshleyDodd/Reachability.swift — 는 내부 SCNetworkReachability 메커니즘을 사용합니다. 이러한 라이브러리는 편리한 Swift/Objective-C 인터페이스, 상태 메모이제이션 및 스레드 안전 콜백을 추가하면서 동일한 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는 인터페이스 유형을 결정하기 위해 이러한 플래그를 고려합니다.
iOS 앱에서 Reachability를 사용하는 표준 패턴은 인스턴스 생성, 알림 구독 및 상태 변경 대응을 포함합니다. 아래 예제는 네트워크 변경 시 UI를 업데이트하기 위한 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가 연결 가능하다고 표시하지만 요청이 타임아웃 내에 실패하는 경우 — 서버 측 문제나 캡티브 포털이 있을 가능성이 높습니다. 이 경우 사용자에게 서버를 사용할 수 없다는 메시지를 표시할 수 있습니다.
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)을 확인하려면 CoreTelephony의 CTTelephonyNetworkInfo가 필요합니다. Reachability를 CoreTelephony와 결합하면 앱이 콘텐츠 품질을 선택할 수 있습니다: 5G에서는 4K 스트리밍, 4G/LTE에서는 HD, 3G에서는 SD 또는 오디오 전용.
Apple은 iOS 12부터 모든 새 프로젝트에서 Reachability를 NWPathMonitor로 교체할 것을 권장합니다. 주요 이유는 NWPathMonitor가 최신 Network 프레임워크의 일부이며, Swift로 작성되었고, Combine을 지원하며, C 호환성 없이 상세한 네트워크 경로 정보를 제공하기 때문입니다.
마이그레이션 프로세스에는 SCNetworkReachability를 NWPathMonitor로 교체하고, NotificationCenter에서 pathUpdateHandler 클로저 또는 Combine 퍼블리셔로 전환하는 것이 포함됩니다. 네트워크 상태 처리 알고리즘과 로직은 동일하게 유지됩니다 — 모니터링 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을 지원하는 프로젝트의 경우 NWPathMonitor와 함께 조건부 컴파일 #available(iOS 12, *)을 사용하고 Reachability를 폴백으로 사용하세요. 이렇게 하면 이전 기기 지원을 잃지 않고 점진적으로 마이그레이션할 수 있습니다.
마이그레이션의 주요 이점은 네트워크 경로 세분화입니다. NWPathMonitor는 단순히 ‘연결 가능/연결 불가’뿐만 아니라 각 인터페이스 유형, 비용, 우선순위, 프록시 및 VPN 지원도 보고합니다. 이는 개발자에게 현재 네트워크 조건에 맞게 애플리케이션 동작을 조정할 수 있는 더 많은 데이터를 제공합니다.
자주 묻는 질문
SCNetworkReachability 기반 Reachability는 iPhone OS 2(iOS 2)부터 사용 가능합니다. 라이브러리는 현재 버전을 포함한 모든 iOS 버전에서 작동합니다. 제한 사항은 OS 버전이 아닌 정보 세분화와 관련이 있습니다 — 이전 버전에서는 4G와 5G를 구분할 수 없습니다.
Reachability는 SCNetworkReachability — 패킷을 보내지 않고 네트워크 스택 수준에서 호스트 연결 가능성을 평가하는 시스템 서비스 — 를 사용합니다. Ping은 ICMP 패킷을 보내고 트래픽을 소비하며 방화벽에 의해 차단될 수 있습니다. Reachability는 자주 확인할 때 더 빠르고 안전합니다.
네, Reachability는 ObservableObject 또는 Combine을 통해 SwiftUI에서 작동합니다. NotificationCenter를 구독하는 클래스로 래핑하고 @Published를 통해 상태를 게시하세요. 새 SwiftUI 프로젝트의 경우 반응형 View 업데이트를 위해 Combine 퍼블리셔와 함께 NWPathMonitor를 권장합니다.
Reachability는 SCNetworkReachabilityFlags 비트마스크에서 kSCNetworkReachabilityFlagsIsWWAN 플래그를 확인합니다. 플래그가 설정된 경우 — 셀룰러 네트워크(WWAN)를 통한 연결, 설정되지 않았고 호스트가 Reachable인 경우 — Wi-Fi를 통한 연결입니다. CoreTelephony 없이 유형을 구분하는 유일한 방법입니다.
SCNetworkReachability는 네트워크 수준에서 호스트 연결 가능성을 확인하지만 상위 프로토콜 작동을 보장하지는 않습니다. 가능한 원인: 캡티브 포털, DNS 차단, 프록시 서버 또는 방화벽. Reachability는 첫 번째 필터이지만 실제 HTTP 요청을 대체할 수는 없습니다.
요약
턴키 방식의 모바일 애플리케이션을 개발해 드립니다
IT Sectr는 2017년부터 스타트업과 기업을 위한 iOS 및 Android 애플리케이션을 만듭니다. 저희가 상담해 드리고 최적의 솔루션을 제안하겠습니다.