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 ที่สะดวก การจดจำสถานะ และ callback ที่ปลอดภัยต่อเธรด ในขณะที่ยังคงพื้นฐาน SystemConfiguration เดิมไว้
กลไกหลักของ Reachability คือฟังก์ชัน SCNetworkReachabilityCreateWithName ซึ่งสร้างออบเจกต์ติดตามสำหรับโฮสต์ที่ระบุ จากนั้นเรียก SCNetworkReachabilityGetFlags — การตรวจสอบแบบซิงโครนัสที่ส่งคืนบิตมาสก์ของ SCNetworkReachabilityFlags พร้อมสถานะเครือข่ายปัจจุบัน
สำหรับการตรวจสอบแบบอะซิงโครนัส จะใช้ SCNetworkReachabilitySetCallback ซึ่งลงทะเบียนฟังก์ชัน callback แบบ C callback จะทำงานบน RunLoop ปัจจุบันเมื่อสถานะการเข้าถึงของโฮสต์เปลี่ยนแปลง Reachability ห่อหุ้ม C-callback นี้เป็นเมธอด 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 เพื่ออัปเดต 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 — แอปไม่แสดงสปินเนอร์ในโหมดออฟไลน์
สำหรับการตรวจสอบที่แม่นยำยิ่งขึ้น ให้รวม 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 เทียบกับ 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 เป็นตัวสำรอง ซึ่งช่วยให้ย้ายได้ทีละน้อยโดยไม่สูญเสียการรองรับอุปกรณ์เก่า
ข้อได้เปรียบหลักของการย้ายคือ รายละเอียดเส้นทางเครือข่าย 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 เราจะให้คำแนะนำและเสนอวิธีแก้ปัญหาที่ดีที่สุดแก่คุณ
อ่านเพิ่มเติม