RxSwift هي مكتبة برمجة تفاعلية للغة Swift تطبق نمط Observable. وفقاً لـ ReactiveX، 2025، فهي أشهر تطبيق لـ Reactive Extensions في نظام Apple البيئي. Observable يعمل كمصدر للأحداث، بينما Observer يشترك لاستلامها.
الرئيسية
RxSwift هي مكتبة برمجة تفاعلية للغة Swift، منقولة من Reactive Extensions (Rx). تتيح وصف البرامج غير المتزامنة والقائمة على الأحداث من خلال Observable Sequence — سلسلة من البيانات متاحة عبر الزمن. يستخدم مطورو iOS RxSwift لمعالجة طلبات الشبكة وأحداث واجهة المستخدم والبيانات المتدفقة دون استدعاءات متداخلة.
يتكون أساس RxSwift من بروتوكولين رئيسيين: ObservableType — مصدر أحداث يمكنه إصدار ثلاثة أنواع من الإشارات: .next(value) و .error(error) و .completed. يشترك Observer في Observable عبر طريقة subscribe ويستلم هذه الأحداث. يسمى هذا النموذج Reactive Streams ويضمن عدم فقدان أي حدث مع اشتراك صحيح.
يوفر RxSwift أكثر من 300 عامل للعمل مع التدفقات: map يحول كل حدث، filter يمرر فقط الأحداث المتطابقة، flatMap يفك Observables المتداخلة في تدفق واحد. يتم ربط العوامل في سلاسل، مما ينشئ خط أنابيب تصريحي لمعالجة البيانات دون آثار جانبية.
بالإضافة إلى Observable الأساسي، يوفر RxSwift أنواعاً مغلفة متخصصة. Single يصدر قيمة واحدة بالضبط أو خطأ — مثالي لطلبات HTTP. Completable يكمل بنجاح أو خطأ بدون قيمة — لعمليات الكتابة. Maybe يجمع كلا السيناريوهين: يمكن أن يكمل بقيمة أو بدون قيمة أو بخطأ. هذه الأنواع الخاصة تبسط الدلالات وتجعل الكود موثقاً ذاتياً.
البرمجة التفاعلية في RxSwift مبنية على نمط Observer. ObservableSequence مشابه لـ Sequence من المكتبة القياسية، ولكن مع وصول غير متزامن للعناصر. يتم تمرير تدفق الأحداث عبر سلسلة من العوامل، كل عامل يعيد ObservableSequence جديدة دون تغيير الأصلية.
العوامل في RxSwift هي دوال بحتة تأخذ ObservableSequence واحدة وتعيد أخرى جديدة. على سبيل المثال، map ينشئ تسلسلاً جديداً بتطبيق تحويل على كل عنصر. بدمج العوامل، يبني المطور خط أنابيب حيث تمر البيانات عبر جميع مراحل المعالجة دون متغيرات وسيطة.
Schedulers هي تجريد فوق خيوط التنفيذ في RxSwift. يحدد Scheduler أي خيط سينفذ الكود: MainScheduler — خيط واجهة المستخدم، SerialDispatchQueueScheduler — قائمة انتظار خلفية. يحدد العاملان subscribeOn و observeOn أين يتم العمل وأين تتم معالجة النتائج على التوالي.
يتضمن RxSwift عدة أنواع أساسية، كل منها يحل مهمته الخاصة في خط الأنابيب التفاعلي. Single هو Observable يصدر قيمة واحدة بالضبط أو خطأ، مناسب لطلبات الشبكة. Completable يكمل بنجاح أو خطأ بدون قيمة. Maybe يجمع خصائص Single و Completable.
Subject هو Observable ساخن يعمل أيضاً كـ Observer. PublishSubject يصدر فقط الأحداث الجديدة للمشتركين، BehaviorSubject — آخر حدث بالإضافة إلى الأحداث الجديدة. Relay هو متغير من Subject لا يصدر .error أو .completed، مما يضمن استمرارية التدفق. BehaviorRelay يخزن القيمة الحالية ومناسب لواجهة المستخدم المدفوعة بالحالة.
DisposeBag هو مجموعة من Disposables تلغي تلقائياً جميع الاشتراكات عند إلغاء تخصيصها. في iOS، يتم إضافة DisposeBag عادةً إلى UIViewController أو UIView. عند إغلاق الشاشة، يتم مسح DisposeBag — وهذا يمنع تسرب الذاكرة والوصول إلى عناصر واجهة مستخدم غير موجودة.
أدناه مثال على إنشاء Observable من مصفوفة بيانات باستخدام عامل map لتحويل السلاسل النصية:
let observable = Observable.of("Swift", "RxSwift", "Reactive")
observable
.map { $0.uppercased() }
.subscribe(onNext: { value in
print("Received: \(value)")
})
.disposed(by: disposeBag)
المثال الثاني يوضح دمج طلبي شبكة باستخدام zip — العامل ينتظر حتى يصدر كلا Observable قيمة ويدمج النتائج في tuple:
let first = fetchUser(id: "123")
let second = fetchPosts(userId: "123")
Observable
.zip(first, second)
.observe(on: MainScheduler.instance)
.subscribe(onNext: { user, posts in
updateUI(user: user, posts: posts)
})
.disposed(by: disposeBag)
المثال الثالث يوضح استخدام BehaviorRelay لتخزين الحالة وتحديث واجهة المستخدم تلقائياً عند التغييرات: كل تغيير state.accept() ينقل فوراً إلى المشتركين، وهو مثالي لأنماط الحالة في بنية MVVM.
let state = BehaviorRelay(value: "idle")
state
.subscribe(onNext: { status in
print("Status: \(status)")
})
.disposed(by: disposeBag)
state.accept("loading") // Prints: Status: loading
RxSwift يختلف عن الطرق التقليدية غير المتزامنة (Delegation, NotificationCenter, Callback) في طبيعته التصريحية وقابليته للتركيب. على عكس Combine، يدعم RxSwift iOS 9+ ولديه المزيد من العوامل. ومع ذلك، Combine مدمج في Foundation و SwiftUI على مستوى اللغة، مما يمنحه ميزة في مشاريع Apple الجديدة.
الميزة الرئيسية لـ RxSwift على GCD (Grand Central Dispatch) هي القدرة على دمج وتحويل تدفقات البيانات على مستوى التجريد بدلاً من إدارة قوائم الانتظار يدوياً. ومع ذلك، يتطلب RxSwift تعلم مفاهيم التفاعلية، مما يزيد من عتبة الدخول للفريق.
في الممارسة العملية، يُستخدم RxSwift في المشاريع الكبيرة حيث تربط السلاسل التفاعلية أحداث واجهة المستخدم ومنطق الأعمال والتفاعل الشبكي في خط أنابيب واحد. على سبيل المثال، في تطبيقات التداول، تتم معالجة تدفقات الأسعار عبر RxSwift: تصل التيكات من WebSocket، تمر عبر التصفية، تُجمع حسب الإطار الزمني وتُعرض على الرسم البياني في الوقت الفعلي. من الصعب تنفيذ هذا السيناريو عبر Delegation أو NotificationCenter دون فقدان قابلية القراءة.
تشمل بدائل RxSwift Combine (iOS 13+)، AsyncSequence من Swift Concurrency (iOS 15+)، بالإضافة إلى مكتبات الطرف الثالث مثل ReactiveSwift دون الارتباط بمنصات Apple. يعتمد الاختيار على الحد الأدنى من إصدار iOS المدعوم وخبرة المطورين. للمشاريع الجديدة iOS 15+، غالباً ما تختار الفرق AsyncSequence — لا يتطلب تثبيت مكتبات ويستخدم تراكيب لغة Swift الأصلية.
الأنماط المعمارية مع RxSwift تتبع عادةً MVVM أو Clean Architecture. تحتوي ViewModel على كل منطق الأعمال كسلاسل Observable، وتشترك View في البيانات المحولة. نمط Input-Output يفصل أحداث الإدخال (النقرات، إدخال النص) عن حالات الإخراج (نص الزر، ظهور مؤشر التحميل). هذا النهج يبسط الاختبار: يتم اختبار ViewModel بدون واجهة مستخدم عبر Schedulers افتراضية.
RxSwift مناسب للمشاريع الصغيرة ذات الشاشتين والمشاريع الكبيرة ذات العشرات من الوحدات. في المشاريع الكبيرة، تخترق السلاسل التفاعلية البنية بأكملها: من مراقبة UserDefaults عبر RxProperty إلى طلبات الشبكة عبر Moya (غلاف RxSwift فوق Alamofire). كل وحدة معزولة وتتواصل عبر واجهات تفاعلية، مما يبسط استبدال التنفيذ دون تغيير المشتركين. مع البنية الصحيحة، يقلل RxSwift من كمية الكود مقارنة بالنهج التقليدية، حيث لا حاجة لكتابة كود متكرر لـ KVO أو Target-Action أو NotificationCenter.
RxSwift يُستخدم بنشاط في المشاريع مع RxDataSources — مكتبة للعمل التفاعلي مع UITableView و UICollectionView. RxDataSources يحسب تلقائياً الفرق بين المجموعات القديمة والجديدة من الخلايا ويطبق تغييرات متحركة. هذا يريح المطور من العمل اليدوي مع beginUpdates/endUpdates ويزيل الأعطال بسبب عدم تناسق البيانات.
لتصحيح أخطاء سلاسل RxSwift، يوجد العامل debug() — يسجل كل الأحداث: subscribe, next, error, completed, dispose. هذه أداة لا غنى عنها عند تطوير خطوط أنابيب تفاعلية معقدة. debug(String) يأخذ معرفاً يظهر في السجلات. لتحليل الذاكرة، RxSwift.Resources.total يظهر العدد الإجمالي لـ Observable و Disposable النشطة في التطبيق — يساعد في تحديد التسريبات عندما لا يتم مسح DisposeBag أو يحتفظ retain cycle باشتراك. العامل الإضافي takeUntil(self.rx.deallocated) يلغي الاشتراك تلقائياً عند إلغاء تخصيص الكائن — وهذه طبقة إضافية من الحماية ضد التسريبات.
عند كتابة كود RxSwift، من المهم اتباع مبدأ Observable واحد لكل اشتراك: يجب ألا ينشئ كل ViewController أكثر من اشتراك واحد لنفس Observable — مما يقلل من خطر حالات السباق. لتخزين Observables مؤقتاً، يُستخدم العامل share()، الذي يحول Observable بارد إلى ساخن مع مخزن replay بحجم 1. عند العمل مع موارد مشتركة، استخدم connect() للتحكم في بدء الإصدار — وهذا يضمن اتصال جميع المشتركين قبل أول حدث.
اختبار كود RxSwift يتم عبر TestScheduler — Scheduler افتراضي يسمح بإدارة الوقت. testScheduler.createHotObservable(values) ينشئ Observable بتسلسل محدد مسبقاً من الأحداث حسب الوقت الافتراضي. testScheduler.start() يبدأ المعالجة. TestScheduler يتيح التحقق من الترتيب والطابع الزمني الافتراضي للأحداث، دون تأخير فعلي، مما يجعل الاختبارات سريعة وحتمية.
الأسئلة الشائعة
Observable هو مصدر بارد: لا يصدر أحداثاً حتى الاشتراك. Subject ساخن: يصدر أحداثاً بغض النظر عن المشتركين ويسمح بإدراج القيم يدوياً عبر onNext. PublishSubject ينقل فقط الأحداث الجديدة، BehaviorSubject — آخر حدث بالإضافة إلى الجديدة.
DisposeBag يخزن جميع اشتراكات Disposable. عندما يتم إلغاء تخصيص DisposeBag (على سبيل المثال، عند إغلاق ViewController)، يتم إلغاء جميع الاشتراكات المخزنة تلقائياً. هذا يضمن أن Observable لن يرسل حدثاً إلى كائن واجهة مستخدم مدمر.
إذا كان الحد الأدنى لإصدار iOS هو 13+ والفريق يعرف SwiftUI — اختر Combine. إذا كان المشروع يدعم iOS 12 أو أقل أو يتطلب مجموعة أكبر من العوامل — RxSwift. Combine يقدم تكاملاً أفضل مع Foundation (URLSession, Timer, NotificationCenter).
Schedulers تجرد خيوط التنفيذ. subscribeOn يحدد على أي Scheduler يتم الاشتراك (عادة في الخلفية). observeOn يحدد على أي Scheduler يتم استلام الأحداث (غالباً MainScheduler لتحديثات واجهة المستخدم). SerialDispatchQueueScheduler يعمل عبر GCD.
نعم، يمكن دمج RxSwift مع SwiftUI عبر ObservableObject. استخدم BehaviorRelay كخصائص @Published: الاشتراك في Relay ينقل التغييرات إلى Combine، ويعيد SwiftUI رسم View عبر @ObservedObject. هذا نمط شائع للهجرة من UIKit إلى SwiftUI.
الخلاصة
سنقوم بتطوير تطبيق جوال جاهز
تقدم IT Sectr تطبيقات iOS وAndroid للشركات الناشئة والشركات منذ عام 2017. سوف نقدم لك النصح ونقترح أفضل حل.
اقرأ أيضًا