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 مريحة، وتخزين الحالة، واستدعاءات آمنة للخيوط، مع الحفاظ على نفس أساس 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. هذا لا يضمن نجاح الطلب (قد يكون الخادم غير متاح)، لكنه يمنع الطلبات الفاشلة بشكل مؤكد ويحسن تجربة المستخدم — التطبيق لا يظهر مؤشر تحميل في وضع عدم الاتصال.
لفحص أكثر دقة، ادمج 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 أو ناشر 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، استخدم التجميع الشرطي #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 للتحديث التفاعلي للعرض.
يتحقق Reachability من العلم kSCNetworkReachabilityFlagsIsWWAN في قناع بت SCNetworkReachabilityFlags. إذا كان العلم مضبوطاً — الاتصال عبر الشبكة الخلوية (WWAN)، إذا لم يكن والمضيف متاح — عبر Wi-Fi. هذه هي الطريقة الوحيدة للتمييز بين الأنواع دون CoreTelephony.
يتحقق SCNetworkReachability من إمكانية الوصول إلى المضيف على مستوى الشبكة ولكنه لا يضمن عمل البروتوكولات الأعلى. الأسباب المحتملة: بوابة مقيدة، حظر DNS، خادم بروكسي أو جدار حماية. Reachability هو الفلتر الأول ولكنه ليس بديلاً لطلب HTTP الفعلي.
الملخص
سنقوم بتطوير تطبيق جوال جاهز
تقدم IT Sectr تطبيقات iOS وAndroid للشركات الناشئة والشركات منذ عام 2017. سوف نقدم لك النصح ونقترح أفضل حل.