Reachability là một thư viện dành cho iOS và macOS được xây dựng trên framework SystemConfiguration, cho phép kiểm tra khả năng khả dụng của kết nối Internet và theo dõi các thay đổi của nó. Theo Tài liệu Apple Developer (2025), Reachability sử dụng SCNetworkReachability để giám sát mạng không đồng bộ. Thư viện Reachability đã là tiêu chuẩn cho các dự án iOS trong một thời gian dài cho đến khi NWPathMonitor gốc xuất hiện.
Những điểm chính
Reachability là một thư viện mẫu của Apple minh họa việc sử dụng framework SystemConfiguration để giám sát mạng. Mã nguồn được xuất bản trong Tài liệu Apple Developer như một ví dụ, nhưng cộng đồng đã áp dụng nó như một công cụ tiêu chuẩn để kiểm tra kết nối trong các dự án iOS.
Thư viện dựa trên SCNetworkReachability — một hàm C từ SystemConfiguration đánh giá khả năng truy cập của một máy chủ từ xa hoặc địa chỉ IP. Khi tạo Reachability, bạn chỉ định tên máy chủ (ví dụ: google.com) hoặc địa chỉ IP, và thư viện kiểm tra không đồng bộ xem máy chủ này có thể truy cập được qua các giao diện mạng hiện tại của thiết bị hay không.
Sự phổ biến của Reachability đến từ sự đơn giản của nó: chỉ cần tạo một phiên bản, đăng ký thông báo qua NotificationCenter và lắng nghe kReachabilityChangedNotification. Đáp lại, ứng dụng nhận được trạng thái: NotReachable, ReachableViaWiFi hoặc ReachableViaWWAN (dữ liệu di động).
Reachability lần đầu tiên xuất hiện trong iPhone OS 2 (2008) cùng với framework SystemConfiguration. Trong một thập kỷ, nó là cách gốc duy nhất để giám sát trạng thái mạng trong iOS. Với sự ra mắt của iOS 12 và framework Network, Apple khuyến nghị NWPathMonitor như một giải pháp thay thế, nhưng Reachability vẫn được hỗ trợ.
Nhiều lớp bao bọc của bên thứ ba — AFNetworking, Alamofire, AshleyDodd/Reachability.swift — sử dụng cơ chế SCNetworkReachability nội bộ. Các thư viện này thêm giao diện Swift/Objective-C thuận tiện, ghi nhớ trạng thái và callback an toàn luồng, trong khi vẫn giữ nguyên nền tảng SystemConfiguration.
Cơ chế chính của Reachability là hàm SCNetworkReachabilityCreateWithName, tạo một đối tượng theo dõi cho máy chủ được chỉ định. Sau đó, SCNetworkReachabilityGetFlags được gọi — một kiểm tra đồng bộ trả về mặt nạ bit SCNetworkReachabilityFlags với trạng thái mạng hiện tại.
Để giám sát không đồng bộ, SCNetworkReachabilitySetCallback được sử dụng, đăng ký một hàm callback C. Callback được thực thi trên RunLoop hiện tại khi trạng thái khả năng truy cập của máy chủ thay đổi. Reachability bao bọc callback C này thành một phương thức Objective-C và gửi thông báo qua 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 là một mặt nạ bit mã hóa trạng thái mạng. Cờ kSCNetworkReachabilityFlagsReachable cho biết máy chủ có thể truy cập được. kSCNetworkReachabilityFlagsConnectionRequired — cần thiết lập kết nối. Sự kết hợp của các cờ xác định liệu ứng dụng có thể gửi dữ liệu hay không.
Cờ bổ sung: kSCNetworkReachabilityFlagsIsWWAN — kết nối qua mạng di động (iOS), kSCNetworkReachabilityFlagsInterventionRequired — cần can thiệp của người dùng (ví dụ: cho VPN). Reachability xem xét các cờ này để xác định loại giao diện.
Mẫu tiêu chuẩn để sử dụng Reachability trong ứng dụng iOS bao gồm tạo một phiên bản, đăng ký thông báo và phản ứng với thay đổi trạng thái. Ví dụ dưới đây cho thấy tích hợp với NotificationCenter để cập nhật giao diện người dùng khi mạng thay đổi.
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("Đã kết nối qua Wi-Fi")
case .cellular:
print("Đã kết nối qua di động")
case .unavailable:
print("Không có kết nối")
}
}
}
}
Trước khi thực hiện yêu cầu HTTP, bạn có thể kiểm tra khả năng khả dụng của mạng một cách đồng bộ: reachability.connection != .unavailable. Điều này không đảm bảo yêu cầu thành công (máy chủ có thể không khả dụng), nhưng ngăn chặn các yêu cầu chắc chắn thất bại và cải thiện UX — ứng dụng không hiển thị spinner ở chế độ ngoại tuyến.
Để kiểm tra chính xác hơn, kết hợp Reachability với thời gian chờ URLSession. Nếu Reachability hiển thị có thể truy cập nhưng yêu cầu thất bại trong thời gian chờ — có thể có vấn đề phía máy chủ hoặc cổng captive. Trong trường hợp đó, bạn có thể hiển thị cho người dùng thông báo máy chủ không khả dụng.
Reachability phân biệt ba trạng thái kết nối chính: Wi-Fi, dữ liệu di động (WWAN) và không khả dụng. WWAN bao gồm tất cả các loại kết nối di động — 2G, 3G, 4G/LTE, 5G. Thư viện không cung cấp chi tiết trong WWAN, vì vậy để phân biệt 4G và 5G cần CoreTelephony.
| Trạng thái | Cờ SCNetwork | Mô tả |
|---|---|---|
| ReachableViaWiFi | Reachable + !IsWWAN | Kết nối qua mạng Wi-Fi với quyền truy cập máy chủ |
| ReachableViaWWAN | Reachable + IsWWAN | Kết nối qua mạng di động (2G-5G) |
| NotReachable | !Reachable | Máy chủ không thể truy cập qua bất kỳ giao diện nào |
| ConnectionRequired | Reachable + ConnectionRequired | Cần thiết lập kết nối (VPN, PPPoE) |
Reachability không phân biệt Ethernet, đường hầm VPN hoặc kết nối đa đường — tất cả các giao diện không phải WWAN được phân loại là Wi-Fi. Hạn chế này xuất phát từ kiến trúc SystemConfiguration, không cung cấp thông tin chi tiết về giao diện mạng ngoài phân loại cơ bản.
Để xác định loại kết nối di động cụ thể (4G vs 5G), cần CTTelephonyNetworkInfo từ CoreTelephony. Kết hợp Reachability với CoreTelephony cho phép ứng dụng chọn chất lượng nội dung: trên 5G — phát trực tiếp 4K, trên 4G/LTE — HD, trên 3G — SD hoặc chỉ âm thanh.
Apple khuyến nghị thay thế Reachability bằng NWPathMonitor trong tất cả các dự án mới bắt đầu từ iOS 12. Lý do chính là NWPathMonitor là một phần của framework Network hiện đại, được viết bằng Swift, hỗ trợ Combine và cung cấp thông tin chi tiết về đường dẫn mạng mà không cần tương thích C.
Quy trình di chuyển bao gồm thay thế SCNetworkReachability bằng NWPathMonitor, chuyển từ NotificationCenter sang closure pathUpdateHandler hoặc publisher Combine. Thuật toán và logic xử lý trạng thái mạng vẫn giữ nguyên — chỉ có API giám sát thay đổi.
protocol NetworkMonitorProtocol {
var isReachable: Bool { get }
var connectionType: ConnectionType { get }
func startMonitoring()
func stopMonitoring()
}
enum ConnectionType {
case wifi, cellular, ethernet, unavailable
}
// Triển khai hiện đại sử dụng 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()
}
}
Đối với các dự án hỗ trợ iOS 12+, hãy thay thế hoàn toàn Reachability bằng NWPathMonitor. Đối với các dự án hỗ trợ iOS 11, sử dụng biên dịch có điều kiện #available(iOS 12, *) với NWPathMonitor và Reachability như một giải pháp dự phòng. Điều này cho phép di chuyển dần dần mà không mất hỗ trợ cho các thiết bị cũ.
Lợi thế chính của việc di chuyển là chi tiết đường dẫn mạng. NWPathMonitor báo cáo không chỉ “có thể truy cập/không thể truy cập” mà còn loại của từng giao diện, chi phí của chúng, ưu tiên, hỗ trợ proxy và VPN. Điều này cung cấp cho nhà phát triển nhiều dữ liệu hơn để điều chỉnh hành vi ứng dụng theo điều kiện mạng hiện tại.
Các câu hỏi thường gặp
Reachability trên SCNetworkReachability có sẵn từ iPhone OS 2 (iOS 2). Thư viện hoạt động trên tất cả các phiên bản iOS, bao gồm cả các phiên bản hiện tại. Các hạn chế không liên quan đến phiên bản HĐH mà liên quan đến chi tiết thông tin — các phiên bản cũ không phân biệt được 4G và 5G.
Reachability sử dụng SCNetworkReachability — một dịch vụ hệ thống đánh giá khả năng truy cập máy chủ ở cấp độ ngăn xếp mạng mà không gửi gói tin. Ping gửi các gói ICMP và tiêu thụ lưu lượng, đồng thời có thể bị chặn bởi tường lửa. Reachability nhanh hơn và an toàn hơn cho việc kiểm tra thường xuyên.
Có, Reachability hoạt động trong SwiftUI thông qua ObservableObject hoặc Combine. Bọc nó trong một lớp đã đăng ký NotificationCenter và xuất bản trạng thái qua @Published. Đối với các dự án SwiftUI mới, chúng tôi khuyến nghị NWPathMonitor với publisher Combine để cập nhật View phản ứng.
Reachability kiểm tra cờ kSCNetworkReachabilityFlagsIsWWAN trong mặt nạ bit SCNetworkReachabilityFlags. Nếu cờ được đặt — kết nối qua mạng di động (WWAN), nếu không và máy chủ Reachable — qua Wi-Fi. Đây là cách duy nhất để phân biệt các loại mà không cần CoreTelephony.
SCNetworkReachability kiểm tra khả năng truy cập máy chủ ở cấp độ mạng nhưng không đảm bảo hoạt động của các giao thức cấp cao hơn. Nguyên nhân có thể: cổng captive, chặn DNS, máy chủ proxy hoặc tường lửa. Reachability là bộ lọc đầu tiên nhưng không thay thế cho yêu cầu HTTP thực tế.
Tổng kết
Chúng tôi sẽ phát triển ứng dụng di động chìa khóa trao tay
IT Sectr tạo các ứng dụng iOS và Android cho các công ty khởi nghiệp và doanh nghiệp từ năm 2017. Chúng tôi sẽ tư vấn và đề xuất giải pháp tốt nhất cho bạn.
Đọc thêm