RxSwift — ما هو، المفاهيم الأساسية والبرمجة التفاعلية

المؤلف: IT Sectr نُشر: 2026-03-17 وقت القراءة: 8 دق

RxSwift هي مكتبة برمجة تفاعلية للغة Swift تطبق نمط Observable. وفقاً لـ ReactiveX، 2025، فهي أشهر تطبيق لـ Reactive Extensions في نظام Apple البيئي. Observable يعمل كمصدر للأحداث، بينما Observer يشترك لاستلامها.

الرئيسية

  • RxSwift — تطبيق Reactive Extensions للغة Swift مع دعم Observable و Subject وأكثر من 300 عامل
  • Observable — مصدر أحداث يصدر قيماً أو أخطاءً أو إشارة إكمال
  • Subject — هو في نفس الوقت Observable و Observer، يسمح بإدراج الأحداث يدوياً في التدفق
  • DisposeBag — آلية إدارة ذاكرة تلقائية تلغي الاشتراكات عند إلغاء التخصيص
  • Schedulers — تدير خيوط التنفيذ، مما يسمح بالتبديل بين قوائم الانتظار الرئيسية والخلفية

ما هو RxSwift؟

RxSwift هي مكتبة برمجة تفاعلية للغة Swift، منقولة من Reactive Extensions (Rx). تتيح وصف البرامج غير المتزامنة والقائمة على الأحداث من خلال Observable Sequence — سلسلة من البيانات متاحة عبر الزمن. يستخدم مطورو iOS RxSwift لمعالجة طلبات الشبكة وأحداث واجهة المستخدم والبيانات المتدفقة دون استدعاءات متداخلة.

Observable و Observer

يتكون أساس RxSwift من بروتوكولين رئيسيين: ObservableType — مصدر أحداث يمكنه إصدار ثلاثة أنواع من الإشارات: .next(value) و .error(error) و .completed. يشترك Observer في Observable عبر طريقة subscribe ويستلم هذه الأحداث. يسمى هذا النموذج Reactive Streams ويضمن عدم فقدان أي حدث مع اشتراك صحيح.

عوامل التحويل

يوفر RxSwift أكثر من 300 عامل للعمل مع التدفقات: map يحول كل حدث، filter يمرر فقط الأحداث المتطابقة، flatMap يفك Observables المتداخلة في تدفق واحد. يتم ربط العوامل في سلاسل، مما ينشئ خط أنابيب تصريحي لمعالجة البيانات دون آثار جانبية.

الأنواع الخاصة: Single, Completable, Maybe

بالإضافة إلى Observable الأساسي، يوفر RxSwift أنواعاً مغلفة متخصصة. Single يصدر قيمة واحدة بالضبط أو خطأ — مثالي لطلبات HTTP. Completable يكمل بنجاح أو خطأ بدون قيمة — لعمليات الكتابة. Maybe يجمع كلا السيناريوهين: يمكن أن يكمل بقيمة أو بدون قيمة أو بخطأ. هذه الأنواع الخاصة تبسط الدلالات وتجعل الكود موثقاً ذاتياً.

كيف تعمل البرمجة التفاعلية في RxSwift

البرمجة التفاعلية في RxSwift مبنية على نمط Observer. ObservableSequence مشابه لـ Sequence من المكتبة القياسية، ولكن مع وصول غير متزامن للعناصر. يتم تمرير تدفق الأحداث عبر سلسلة من العوامل، كل عامل يعيد ObservableSequence جديدة دون تغيير الأصلية.

سلاسل العوامل

العوامل في RxSwift هي دوال بحتة تأخذ ObservableSequence واحدة وتعيد أخرى جديدة. على سبيل المثال، map ينشئ تسلسلاً جديداً بتطبيق تحويل على كل عنصر. بدمج العوامل، يبني المطور خط أنابيب حيث تمر البيانات عبر جميع مراحل المعالجة دون متغيرات وسيطة.

Schedulers وخيوط التنفيذ

Schedulers هي تجريد فوق خيوط التنفيذ في RxSwift. يحدد Scheduler أي خيط سينفذ الكود: MainScheduler — خيط واجهة المستخدم، SerialDispatchQueueScheduler — قائمة انتظار خلفية. يحدد العاملان subscribeOn و observeOn أين يتم العمل وأين تتم معالجة النتائج على التوالي.

المكونات الأساسية لـ RxSwift

يتضمن RxSwift عدة أنواع أساسية، كل منها يحل مهمته الخاصة في خط الأنابيب التفاعلي. Single هو Observable يصدر قيمة واحدة بالضبط أو خطأ، مناسب لطلبات الشبكة. Completable يكمل بنجاح أو خطأ بدون قيمة. Maybe يجمع خصائص Single و Completable.

Subject و Relay

Subject هو Observable ساخن يعمل أيضاً كـ Observer. PublishSubject يصدر فقط الأحداث الجديدة للمشتركين، BehaviorSubject — آخر حدث بالإضافة إلى الأحداث الجديدة. Relay هو متغير من Subject لا يصدر .error أو .completed، مما يضمن استمرارية التدفق. BehaviorRelay يخزن القيمة الحالية ومناسب لواجهة المستخدم المدفوعة بالحالة.

DisposeBag

DisposeBag هو مجموعة من Disposables تلغي تلقائياً جميع الاشتراكات عند إلغاء تخصيصها. في iOS، يتم إضافة DisposeBag عادةً إلى UIViewController أو UIView. عند إغلاق الشاشة، يتم مسح DisposeBag — وهذا يمنع تسرب الذاكرة والوصول إلى عناصر واجهة مستخدم غير موجودة.

أمثلة كود RxSwift

أدناه مثال على إنشاء Observable من مصفوفة بيانات باستخدام عامل map لتحويل السلاسل النصية:

swift
let observable = Observable.of("Swift", "RxSwift", "Reactive")

observable
    .map { $0.uppercased() }
    .subscribe(onNext: { value in
        print("Received: \(value)")
    })
    .disposed(by: disposeBag)

المثال الثاني يوضح دمج طلبي شبكة باستخدام zip — العامل ينتظر حتى يصدر كلا Observable قيمة ويدمج النتائج في tuple:

swift
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.

swift
let state = BehaviorRelay(value: "idle")

state
    .subscribe(onNext: { status in
        print("Status: \(status)")
    })
    .disposed(by: disposeBag)

state.accept("loading") // Prints: Status: loading

RxSwift مقابل الطرق الأخرى

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

عند كتابة كود RxSwift، من المهم اتباع مبدأ Observable واحد لكل اشتراك: يجب ألا ينشئ كل ViewController أكثر من اشتراك واحد لنفس Observable — مما يقلل من خطر حالات السباق. لتخزين Observables مؤقتاً، يُستخدم العامل share()، الذي يحول Observable بارد إلى ساخن مع مخزن replay بحجم 1. عند العمل مع موارد مشتركة، استخدم connect() للتحكم في بدء الإصدار — وهذا يضمن اتصال جميع المشتركين قبل أول حدث.

اختبار كود RxSwift يتم عبر TestScheduler — Scheduler افتراضي يسمح بإدارة الوقت. testScheduler.createHotObservable(values) ينشئ Observable بتسلسل محدد مسبقاً من الأحداث حسب الوقت الافتراضي. testScheduler.start() يبدأ المعالجة. TestScheduler يتيح التحقق من الترتيب والطابع الزمني الافتراضي للأحداث، دون تأخير فعلي، مما يجعل الاختبارات سريعة وحتمية.

الأسئلة الشائعة

ما الفرق بين Observable و Subject في RxSwift؟

Observable هو مصدر بارد: لا يصدر أحداثاً حتى الاشتراك. Subject ساخن: يصدر أحداثاً بغض النظر عن المشتركين ويسمح بإدراج القيم يدوياً عبر onNext. PublishSubject ينقل فقط الأحداث الجديدة، BehaviorSubject — آخر حدث بالإضافة إلى الجديدة.

كيف يمنع DisposeBag تسرب الذاكرة في RxSwift؟

DisposeBag يخزن جميع اشتراكات Disposable. عندما يتم إلغاء تخصيص DisposeBag (على سبيل المثال، عند إغلاق ViewController)، يتم إلغاء جميع الاشتراكات المخزنة تلقائياً. هذا يضمن أن Observable لن يرسل حدثاً إلى كائن واجهة مستخدم مدمر.

ماذا تختار: RxSwift أم Combine لمشروع iOS جديد؟

إذا كان الحد الأدنى لإصدار iOS هو 13+ والفريق يعرف SwiftUI — اختر Combine. إذا كان المشروع يدعم iOS 12 أو أقل أو يتطلب مجموعة أكبر من العوامل — RxSwift. Combine يقدم تكاملاً أفضل مع Foundation (URLSession, Timer, NotificationCenter).

كيف تعمل Schedulers في RxSwift؟

Schedulers تجرد خيوط التنفيذ. subscribeOn يحدد على أي Scheduler يتم الاشتراك (عادة في الخلفية). observeOn يحدد على أي Scheduler يتم استلام الأحداث (غالباً MainScheduler لتحديثات واجهة المستخدم). SerialDispatchQueueScheduler يعمل عبر GCD.

هل يمكن استخدام RxSwift مع SwiftUI؟

نعم، يمكن دمج RxSwift مع SwiftUI عبر ObservableObject. استخدم BehaviorRelay كخصائص @Published: الاشتراك في Relay ينقل التغييرات إلى Combine، ويعيد SwiftUI رسم View عبر @ObservedObject. هذا نمط شائع للهجرة من UIKit إلى SwiftUI.

الخلاصة

  • RxSwift — مكتبة برمجة تفاعلية مبنية على Reactive Extensions ونمط Observable
  • Observable يصدر ثلاثة أنواع من الإشارات: .next و .error و .completed
  • Subject (PublishSubject, BehaviorSubject) يجمع Observable و Observer للتدفقات الساخنة
  • DisposeBag يدير دورة حياة الاشتراكات ويمنع تسرب الذاكرة
  • العوامل (map, filter, flatMap, zip) تتيح بناء سلاسل معالجة تصريحية
  • Schedulers تبدل التنفيذ بين قوائم الانتظار الخلفية وخيط واجهة المستخدم
  • للتطوير الجديد على iOS 13+، فكر في Combine كبديل مدمج

سنقوم بتطوير تطبيق جوال جاهز

تقدم IT Sectr تطبيقات iOS وAndroid للشركات الناشئة والشركات منذ عام 2017. سوف نقدم لك النصح ونقترح أفضل حل.

مناقشة المشروع

اقرأ أيضًا