RxSwift — ما هو، الإمكانيات والبرمجة التفاعلية

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

RxSwift هي مكتبة برمجة تفاعلية لنظام iOS تطبق نمط Observable والعوامل الوظيفية للعمل مع تدفقات البيانات غير المتزامنة. إنها تنقل مفاهيم ReactiveX (Rx) إلى لغة Swift، مما يوفر واجهة برمجة تطبيقات موحدة لمعالجة الأحداث من واجهة المستخدم وطلبات الشبكة وقواعد البيانات والمؤقتات. وفقًا لـ ReactiveX، 2025، تُستخدم المكتبة في أكثر من 60,000 مشروع على GitHub ولا تزال المعيار للبرمجة التفاعلية في Swift حتى ظهور Combine الأصلي. RxSwift يحل محل المفوضين والإغلاقات والإشعارات بسلسلة معالجة أحداث واحدة.

الخلاصة

  • RxSwift — تنفيذ ReactiveX لـ Swift يعتمد على نمط Observable وسلاسل العوامل
  • Observable — مصدر للأحداث غير المتزامنة يمكن أن يكتمل بنجاح أو بخطأ أو إلى ما لا نهاية
  • Subject — مزيج من Observable و Observer يسمح بإرسال الأحداث يدويًا إلى التدفق
  • Schedulers تتحكم في أي خيط يتم تنفيذ الاشتراك والمراقبة ومعالجة الأحداث
  • العوامل map، flatMap، filter، combineLatest تحول وتدمج التدفقات دون حالات سباق

ما هو RxSwift؟

RxSwift هو منفذ Swift لمكتبة ReactiveX (Rx) التي أنشأتها Microsoft لـ .NET في عام 2012. الفكرة الأساسية لـ Rx هي تمثيل أي مصدر بيانات غير متزامن كسلسلة Observable يمكن تطبيق العوامل الوظيفية عليها. في تطوير iOS، يُستخدم RxSwift لربط أحداث واجهة المستخدم (النقر على الأزرار، إدخال النص، الإيماءات) بمنطق التطبيق دون مفوضين صريحين وtarget-action.

تتكون المكتبة من ثلاث وحدات: RxSwift (النواة — Observable، Operator، Scheduler)، RxCocoa (التكامل مع UIKit — امتدادات rx لـ UIButton، UITextField، UITableView) و RxRelay (Subject بدون أحداث نهائية). هذا الفصل يسمح باستخدام النواة في Swift من جانب الخادم والاختبارات، مع ربط غلاف واجهة المستخدم فقط لتطبيقات iOS.

وفقًا لاستطلاع Stack Overflow، 2025، فإن RxSwift من بين أفضل 5 مكتبات خارجية الأكثر استخدامًا لنظام iOS. السبب الرئيسي لشعبيتها هو المعالجة الموحدة لجميع الأنماط غير المتزامنة: طلبات الشبكة عبر URLSession، الرسوم المتحركة عبر UIViewPropertyAnimator، الإشعارات عبر NotificationCenter والمفوضين عبر DelegateProxy — كل هذا يختزل إلى Observable بدورة حياة يمكن التنبؤ بها.

فلسفة البرمجة التفاعلية

البرمجة التفاعلية هي نموذج يتفاعل فيه البرنامج مع تغييرات البيانات بدلاً من الاستعلام عنها. بدلاً من كتابة «الحصول على البيانات → المعالجة → تحديث واجهة المستخدم»، يصف المطور سلسلة تحويلات: «عندما تتغير البيانات، طبق الفلتر، ثم map، ثم تحديث واجهة المستخدم». ينفذ RxSwift هذا النموذج من خلال سلاسل Observable ذات التنفيذ البطيء — لا يحدث شيء حتى يظهر مشترك.

مكونات RxSwift الرئيسية: Observable، Subject، Disposable

Observable هو النوع الأساسي في RxSwift الذي يمثل سلسلة من الأحداث عبر الزمن. يمكن لـ Observable إرسال ثلاثة أنواع من الأحداث: next (قيمة جديدة)، error (خطأ ينهي التدفق) و completed (إكمال ناجح). هناك Observable محدودة (تكتمل بعد إرسال جميع القيم) و Observable غير محدودة (مثل أحداث واجهة المستخدم — لا تكتمل أبدًا).

Observable ودورة حياته

تشمل دورة الحياة لـ Observable ثلاث مراحل: الإنشاء (create، just، from)، التحويل (العوامل map، filter، flatMap) والاشتراك (subscribe). بدون اشتراك، لا يقوم Observable بأي إجراءات — إنها سلسلة كسولة. بعد الاشتراك، يبدأ Observable في إرسال الأحداث إلى المشترك حتى يكتمل أو يلغي المشترك الاشتراك عبر Disposable.

swift
import RxSwift

// إنشاء Observable من مصفوفة
let numbers = Observable.from([1, 2, 3, 4, 5])

// التحويل عبر العوامل
let squared = numbers
    .filter { $0 % 2 == 0 }
    .map { $0 * $0 }

// الاشتراك مع معالجة الأحداث
let disposable = squared
    .subscribe(onNext: { print($0) },
               onError: { print("Error: \($0)") },
               onCompleted: { print("Done") })

Subject هو نوع يكون في نفس الوقت Observable (يمكن الاشتراك فيه) و Observer (يمكن إرسال الأحداث إليه). يوفر RxSwift أربعة أنواع من Subject: PublishSubject (أحداث جديدة فقط)، BehaviorSubject (بقيمة أولية)، ReplaySubject (تخزين آخر N حدث في المخزن المؤقت) و AsyncSubject (آخر قيمة فقط قبل الإكمال). Subject مفيد لدمج الكود الأمرّي (الإغلاقات، المفوضون) في سلسلة تفاعلية.

Disposable هو رمز إلغاء الاشتراك. عندما لا يريد المشترك تلقي الأحداث بعد الآن، يستدعي disposable.dispose(). عمليًا، يُستخدم DisposeBag: مجموعة من Disposable تلغي تلقائيًا جميع الاشتراكات عند إلغاء تهيئة المالك (مثل UIViewController). هذا يمنع تسرب الذاكرة الحتمي مع الإدارة اليدوية للاشتراكات.

نوع Subjectقيمة أوليةيعيد للمشتركالاستخدام
PublishSubjectلاأحداث جديدة فقطأحداث واجهة المستخدم، إشعارات نادرة
BehaviorSubjectنعمآخر + جديدالحالة، تدفق البيانات
ReplaySubjectلامخزن N + جديدتخزين مؤقت للسجل
AsyncSubjectلاآخر فقطمهام حسابية
PublishRelayلاجديد فقطبدون error/completed

عوامل تحويل وتصفية التدفقات

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

عوامل التحويل تغير كل حدث في التدفق. map يطبق دالة على كل عنصر، flatMap يفك Observable من كل عنصر إلى تدفق مسطح واحد، scan يراكم النتائج الوسيطة (مشابه لـ reduce ولكنه يُصدر كل خطوة). buffer يجمع العناصر حسب الوقت أو العدد، window يقسم التدفق إلى Observable متداخلة حسب النوافذ.

swift
// مثال لسلسلة العوامل: بحث مع debounce
searchTextField.rx.text
    .orEmpty
    .debounce(.milliseconds(300), scheduler: MainScheduler.instance)
    .distinctUntilChanged()
    .flatMapLatest { query -> Observable<[String]> in
        return apiService.search(query)
    }
    .bind(to: tableView.rx.items(cellIdentifier: "Cell")) { _, item, cell in
        cell.textLabel?.text = item
    }
    .disposed(by: disposeBag)

عوامل التصفية تمرر فقط الأحداث التي تفي بشرط. filter يصفّي حسب المسند، distinctUntilChanged يمرر فقط القيم المختلفة عن السابقة، take و takeWhile يحدان من عدد الأحداث. skip و skipWhile يتخطيان أول N حدث أو الأحداث حتى يتحقق شرط. لمعالجة الأخطاء، تُستخدم catchError (اعتراض واستبدال) و retry (إعادة محاولة التسلسل عند الخطأ).

عوامل الدمج تدمج عدة Observables في واحد. combineLatest يدمج أحدث القيم من تدفقات متعددة في مجموعة، zip يزاوج العناصر بنفس المؤشرات، merge يدمج تدفقات متعددة في واحد بترتيب وصول الأحداث. withLatestFrom يدمج حدثًا من التدفق الرئيسي مع آخر قيمة من تدفق آخر — مفيد لأحداث واجهة المستخدم مع الحالة الحالية.

الفئةالعاملالوظيفة
تحويلmapيحول كل قيمة عبر دالة
تحويلflatMapيفك Observables المتداخلة إلى تدفق مسطح
تصفيةfilterيمرر القيم حسب المسند
تصفيةdistinctUntilChangedيمرر القيم المتغيرة فقط
دمجcombineLatestيدمج أحدث القيم من 2+ تدفقات
دمجzipيزاوج العناصر حسب المؤشر
تحكمdebounceيؤخر الأحداث حتى توقف في التدفق
تحكمtakeيأخذ أول N حدث ويكمل التدفق

Schedulers وإدارة خيوط التنفيذ

Scheduler في RxSwift هو تجريد فوق خيط التنفيذ (أو قائمة الانتظار). يحدد Scheduler في أي خيط يتم تنفيذ إنشاء الأحداث والتحويل والاشتراك. على عكس GCD، حيث يحدد المطور صراحةً DispatchQueue، يستخدم RxSwift معلمتين: subscribeOn (في أي خيط يتم تنفيذ Observable) و observeOn (في أي خيط يتم استدعاء المشترك).

MainScheduler و BackgroundScheduler

MainScheduler ينفذ الكود على الخيط الرئيسي — إلزامي لتحديث UIKit (جميع تغييرات واجهة المستخدم يجب أن تحدث على الخيط الرئيسي). SerialDispatchQueueScheduler يغلف قائمة انتظار GCD تسلسلية، ConcurrentDispatchQueueScheduler يغلف قائمة انتظار متزامنة. للمهام الخلفية، يُستخدم ConcurrentDispatchQueueScheduler مع qos: .background أو .utility.

swift
// النمط النموذجي: عمل خلفي + واجهة مستخدم على main
apiService.fetchData()
    .subscribeOn(ConcurrentDispatchQueueScheduler(qos: .background))
    .observeOn(MainScheduler.instance)
    .subscribe(onNext: { data in
        self.tableView.reloadData()
        self.loadingIndicator.stopAnimating()
    })
    .disposed(by: disposeBag)

الاستخدام الصحيح لـ Scheduler يمنع حظر واجهة المستخدم أثناء طلبات الشبكة والحسابات الثقيلة. subscribeOn يؤثر على كل المنبع (جميع العوامل قبل observeOn تُنفذ على المجدول المحدد). observeOn يحول المصب — جميع العوامل بعد observeOn تُنفذ على المجدول المحدد. يمكن أن تحتوي السلسلة على عدة observeOn للتبديل بين الخيوط في مراحل تحويل مختلفة.

SerialDispatchQueueScheduler يضمن المعالجة التسلسلية للأحداث، وهو أمر مهم لسلامة الخيوط للموارد المشتركة. للعمليات عالية التحميل (معالجة الصور، تحليل JSON) استخدم ConcurrentDispatchQueueScheduler — RxSwift سيحافظ على ترتيب الأحداث داخل Observable واحد، لكن Observables مختلفة قد تتم معالجتها بالتوازي.

التطبيق العملي لـ RxSwift في iOS

RxSwift في مشاريع iOS يُستخدم غالبًا لربط واجهة المستخدم بالبيانات عبر سلاسل تفاعلية. يوفر RxCocoa امتدادات rx لجميع مكونات UIKit القياسية: rx.tap لـ UIButton، rx.text لـ UITextField، rx.selectedRow لـ UIPickerView. هذا يسمح بالتخلي عن @IBAction والمفوضين، واستبدالهم باشتراكات تصريحية.

RxSwift مع MVVM

MVVM (Model-View-ViewModel) هو نمط معماري يدير فيه ViewModel الحالة ومنطق الأعمال، ويشترك View في الخصائص التفاعلية لـ ViewModel. RxSwift يتناسب تمامًا مع MVVM: ViewModel ينشر Observable أو Driver للبيانات، ويشترك View فيها عبر bind. ViewModel ليس لديه مرجع إلى View — يُرجع Observable التي يستهلكها View.

swift
class LoginViewModel {
    let email = BehaviorRelay<String>(value: "")
    let password = BehaviorRelay<String>(value: "")

    var isFormValid: Observable<Bool> {
        return Observable
            .combineLatest(email, password) {
                !$0.isEmpty && $0.contains("@") && $1.count >= 6
            }
    }
}

// في ViewController:
viewModel.isFormValid
    .bind(to: loginButton.rx.isEnabled)
    .disposed(by: disposeBag)

طلبات الشبكة هي ثاني أكثر حالات استخدام RxSwift شيوعًا. URLSession.rx.response يغلف طلب HTTP في Observable يُرجع (response, data) عند النجاح أو error عند الفشل. بالدمج مع Codable والعامل map، يتم الحصول على طبقة API تفاعلية مضغوطة: Observable<MyModel> بدون callbacks ومعالجة أخطاء في كل طريقة. عند خطأ الشبكة، العامل retry(3) يعيد محاولة الطلب تلقائيًا ثلاث مرات مع تأخير أسي.

RxSwift مقابل Combine

Combine هو إطار Apple الأصلي الذي تم تقديمه في iOS 13. يحل نفس المهام التي يحلها RxSwift: العمل مع الأحداث غير المتزامنة عبر Publisher و Subscriber والعوامل. ومع ذلك، لدى Combine اختلافات رئيسية: كتابة أخطاء صارمة عبر نوع Failure، دعم Swift Concurrency المدمج (async/await) والتكامل مع SwiftUI عبر @Published و ObservableObject.

RxSwift يتفوق في التوافق مع الإصدارات السابقة — يدعم iOS 8+، بينما يتطلب Combine iOS 13+. RxSwift لديه نظام بيئي أغنى من الامتدادات الخارجية (RxDataSources، RxGesture، RxAnimated) وتوثيق مفصل للعوامل. للمشاريع التي تدعم إصدارات iOS القديمة، يظل RxSwift الخيار الوحيد.

للمشاريع الجديدة على iOS 13+، توصي Apple باستخدام Combine. إنه متكامل بإحكام مع SwiftUI، وله حجم ثنائي أصغر ودعم رسمي. ومع ذلك، فإن ترحيل كود RxSwift الحالي إلى Combine يتطلب إعادة كتابة جميع Observable → Publisher، ونظام RxCocoa البيئي ليس له مكافئ كامل في Combine — UIKit ليس لديه Publisher أصلي لجميع مكونات واجهة المستخدم.

الميزةRxSwiftCombine
الحد الأدنى iOSiOS 8+iOS 13+
نوع الخطأError (أي)Generic Failure
امتدادات UIRxCocoa (UIKit, AppKit)@Published (SwiftUI)
العوامل400+ عامل~100 عامل
Swift Concurrencyعبر bridgeدعم أصلي
الحالةجهة خارجيةApple رسمي

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

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

Observable هو مصدر للأحداث مع تنفيذ بطيء. Subject هو في نفس الوقت Observable و Observer — يمكنك الاشتراك فيه وإرسال أحداث جديدة إليه يدويًا. Subject مفيد لدمج الكود الأمرّي في السلاسل التفاعلية.

متى نستخدم RxSwift بدلاً من Combine؟

RxSwift يُختار عند الحاجة لدعم iOS 11-12، أو عند وجود قاعدة كود RxSwift حالية، أو عند الحاجة إلى نظام بيئي غني بالعوامل (400+ مقابل ~100 في Combine). للمشاريع الجديدة على iOS 13+ يُفضل Combine.

ما هو DisposeBag وما فائدته؟

DisposeBag هو مجموعة من رموز Disposable تلغي تلقائيًا جميع الاشتراكات عند إلغاء تهيئة المالك. بدون DisposeBag، ينشئ الاشتراك مرجعًا قويًا للإغلاق، مما يؤدي إلى تسرب الذاكرة عند تدمير UIViewController.

كيف نتعامل مع الأخطاء في RxSwift؟

استخدم catchError لاستبدال الخطأ بقيمة افتراضية، retry لإعادة محاولة تنفيذ Observable، materialize لتحويل الخطأ إلى حدث. في طبقة واجهة المستخدم، Driver و Signal لا ينقلان الأخطاء — تتم معالجتها داخليًا.

كيف يختلف Driver عن Observable في RxCocoa؟

Driver هو نوع خاص من Observable يضمن التنفيذ على MainScheduler، وغياب الأخطاء ومشاركة الموارد. يضمن Driver أن تحديثات واجهة المستخدم تحدث على الخيط الرئيسي. Observable لا يوفر هذه الضمانات — يلزم observeOn.

الملخص

  • RxSwift هي مكتبة برمجة تفاعلية لنظام iOS تطبق نمط Observable و400+ عامل تحويل
  • Observable، Subject، Disposable هي ثلاثة أنواع أساسية تشكل أساس جميع السلاسل التفاعلية
  • العوامل map، flatMap، filter، combineLatest، debounce تسمح ببناء سلاسل تصريحية بدون حالات سباق
  • Schedulers (subscribeOn / observeOn) تدير خيوط التنفيذ، مما يمنع حظر واجهة المستخدم
  • RxCocoa يوفر امتدادات rx لـ UIKit، ليحل محل المفوضين وtarget-action باشتراكات تفاعلية
  • Combine هو البديل الأصلي من Apple لنظام iOS 13+، لكن RxSwift يظل ملائمًا للإصدارات الأقدم

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

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

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

اقرأ أيضًا