RxSwift یک کتابخانه برنامهنویسی واکنشگرا برای Swift است که الگوی Observable را پیادهسازی میکند. به گفته ReactiveX, 2025، این محبوبترین پیادهسازی Reactive Extensions برای اکوسیستم Apple است. Observable به عنوان منبع رویدادها عمل میکند و Observer برای دریافت آنها مشترک میشود.
نکات اصلی
RxSwift یک کتابخانه برنامهنویسی واکنشگرا برای زبان Swift است که از Reactive Extensions (Rx) منتقل شده است. این کتابخانه امکان توصیف برنامههای ناهمگام و رویدادمحور را از طریق Observable Sequence — دنبالهای از دادههای قابل دسترس در طول زمان — فراهم میکند. توسعهدهندگان iOS از RxSwift برای پردازش درخواستهای شبکه، رویدادهای UI و دادههای جریانی بدون callbackهای تو در تو استفاده میکنند.
اساس RxSwift را دو پروتکل کلیدی تشکیل میدهند: ObservableType — منبع رویدادها که میتواند سه نوع سیگنال منتشر کند: .next(value)، .error(error) و .completed. Observer از طریق متد subscribe در Observable مشترک میشود و این رویدادها را دریافت میکند. چنین مدلی Reactive Streams نامیده میشود و تضمین میکند که با اشتراک صحیح هیچ رویدادی از دست نمیرود.
RxSwift بیش از 300 عملگر برای کار با جریانها فراهم میکند: map هر رویداد را تبدیل میکند، filter فقط موارد مناسب را عبور میدهد، flatMap Observableهای تو در تو را در یک جریان واحد باز میکند. عملگرها در زنجیرهایی ترکیب میشوند و یک خط لوله پردازش اعلانی داده بدون اثرات جانبی ایجاد میکنند.
علاوه بر Observable پایه، RxSwift انواع wrapper تخصصی ارائه میدهد. Single دقیقاً یک مقدار یا خطا منتشر میکند — برای درخواستهای HTTP ایدهآل است. Completable بدون مقدار با موفقیت یا خطا پایان مییابد — برای عملیات نوشتن. Maybe هر دو سناریو را ترکیب میکند: میتواند با مقدار، بدون مقدار یا با خطا پایان یابد. این Traits معناشناسی را سادهتر میکنند و کد را خودمستندساز میکنند.
برنامهنویسی واکنشگرا در RxSwift بر اساس الگوی Observer ساخته شده است. ObservableSequence مشابه Sequence از کتابخانه استاندارد است، اما با دسترسی ناهمگام به عناصر. جریان رویدادها از طریق زنجیرهای از عملگرها منتقل میشود که هر کدام یک ObservableSequence جدید را برمیگرداند بدون اینکه اصلی را تغییر دهد.
عملگرها در RxSwift توابع خالصی هستند که یک ObservableSequence را دریافت کرده و یک مورد جدید برمیگردانند. برای مثال، map یک دنباله جدید ایجاد میکند و تبدیل را به هر عنصر اعمال میکند. با ترکیب عملگرها، توسعهدهنده یک خط لوله میسازد که در آن دادهها بدون متغیرهای میانی از تمام مراحل پردازش عبور میکنند.
Schedulers یک انتزاع بر روی رشتههای اجرا در RxSwift است. Scheduler تعیین میکند که کد در کدام رشته اجرا شود: MainScheduler — رشته UI، SerialDispatchQueueScheduler — صف پسزمینه. عملگرهای subscribeOn و observeOn مشخص میکنند که کار کجا انجام میشود و نتایج کجا پردازش میشوند.
RxSwift شامل چندین نوع پایه است که هر کدام وظیفه خود را در خط لوله واکنشگرا حل میکند. Single — Observableای که دقیقاً یک مقدار یا خطا منتشر میکند، برای درخواستهای شبکه مناسب است. Completable بدون مقدار با موفقیت یا خطا پایان مییابد. Maybe ویژگیهای Single و Completable را ترکیب میکند.
Subject یک Observable داغ است که همزمان نقش Observer را نیز ایفا میکند. PublishSubject فقط رویدادهای جدید را به مشترکان منتشر میکند، BehaviorSubject — آخرین رویداد به علاوه رویدادهای جدید. Relay نوعی از Subject است که .error یا .completed منتشر نمیکند و تداوم جریان را تضمین میکند. BehaviorRelay مقدار فعلی را ذخیره میکند و برای State-driven UI مناسب است.
DisposeBag مجموعهای از Disposable است که به طور خودکار تمام اشتراکها را در هنگام تخصیصزدایی خود لغو میکند. در iOS، DisposeBag معمولاً به UIViewController یا UIView اضافه میشود. هنگام بسته شدن صفحه، DisposeBag پاک میشود — این کار از نشت حافظه و ارجاع به عناصر UI موجود جلوگیری میکند.
در زیر نمونهای از ایجاد Observable از یک آرایه داده با استفاده از عملگر map برای تبدیل رشتهها نشان داده شده است:
let observable = Observable.of("Swift", "RxSwift", "Reactive")
observable
.map { $0.uppercased() }
.subscribe(onNext: { value in
print("دریافت شد: \(value)")
})
.disposed(by: disposeBag)
در مثال دوم، ترکیب دو درخواست شبکه با استفاده از zip نشان داده شده است — عملگر منتظر میماند تا هر دو Observable مقداری منتشر کنند و نتایج را در یک تاپل ترکیب میکند:
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 برای ذخیره وضعیت و بهروزرسانی خودکار UI در هنگام تغییرات را نشان میدهد: هر تغییر state.accept() بلافاصله به مشترکان منتقل میشود که برای الگوهای State در معماری MVVM ایدهآل است.
let state = BehaviorRelay(value: "idle")
state
.subscribe(onNext: { status in
print("وضعیت: \(status)")
})
.disposed(by: disposeBag)
state.accept("loading") // خروجی: وضعیت: loading
RxSwift با روشهای سنتی ناهمگام (Delegation, NotificationCenter, Callback) از نظر اعلانی بودن و ترکیبپذیری متفاوت است. برخلاف Combine، RxSwift از iOS 9+ پشتیبانی میکند و عملگرهای بیشتری دارد. با این حال، Combine در سطح زبان با Foundation و SwiftUI یکپارچه شده است که به آن در پروژههای جدید Apple برتری میدهد.
مزیت اصلی RxSwift نسبت به GCD (Grand Central Dispatch) — امکان ترکیب و تبدیل جریانهای داده در سطح انتزاع به جای مدیریت دستی صفها است. در عین حال، RxSwift نیاز به یادگیری مفاهیم رویکرد واکنشگرا دارد که آستانه ورود برای تیم را افزایش میدهد.
در عمل، RxSwift در پروژههای بزرگی استفاده میشود که در آن زنجیرههای واکنشگرا رویدادهای UI، منطق کسبوکار و تعاملات شبکه را در یک خط لوله واحد متصل میکنند. به عنوان مثال، در برنامههای معاملاتی، جریانهای قیمت از طریق 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 رویدادهای ورودی (لمسها، ورود متن) و حالتهای خروجی (متن دکمه، نمایان بودن loader) را جدا میکند. این رویکرد تست را ساده میکند: ViewModel از طریق Schedulerهای مجازی بدون UI تست میشود.
RxSwift هم برای پروژههای کوچک با چند صفحه و هم برای برنامههای enterprise بزرگ با دهها ماژول مناسب است. در پروژههای بزرگ، زنجیرههای واکنشگرا در سراسر معماری نفوذ میکنند: از مشاهده UserDefaults از طریق RxProperty تا درخواستهای شبکه از طریق Moya (لایه RxSwift روی Alamofire). هر ماژول ایزوله است و از طریق رابطهای واکنشگرا ارتباط برقرار میکند که تعویض پیادهسازی را بدون تغییر مشترکان ساده میکند. با معماری صحیح، RxSwift مقدار کد را در مقایسه با رویکردهای کلاسیک کاهش میدهد زیرا نیازی به نوشتن boilerplate برای KVO، Target-Action یا NotificationCenter نیست.
RxSwift به طور فعال در پروژههای RxDataSources استفاده میشود — کتابخانهای برای کار واکنشگرا با UITableView و UICollectionView. RxDataSources به طور خودکار تفاوت بین مجموعه سلولهای قدیمی و جدید را محاسبه کرده و تغییرات متحرک را اعمال میکند. این کار توسعهدهنده را از کار دستی با beginUpdates/endUpdates رها کرده و در صورت ناسازگاری دادهها از crash جلوگیری میکند.
برای اشکالزدایی زنجیرههای 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 ایجاد کند — این خطر race condition را کاهش میدهد. برای memoization Observable از عملگر share() استفاده میشود که Observable سرد را با بافر replay به اندازه ۱ به گرم تبدیل میکند. هنگام کار با منابع مشترک از connect() برای مدیریت شروع انتشار استفاده کنید — این تضمین میکند که همه مشترکان قبل از اولین رویداد متصل شوند.
تست کد RxSwift از طریق TestScheduler انجام میشود — یک Scheduler مجازی که امکان مدیریت زمان را فراهم میکند. testScheduler.createHotObservable(values) یک Observable با دنبالهای از پیش تعریفشده از رویدادها بر اساس زمان مجازی ایجاد میکند. testScheduler.start() پردازش را آغاز میکند. TestScheduler امکان بررسی ترتیب و زمان وقوع رویدادها بدون تأخیر واقعی را فراهم میکند که تستها را سریع و قطعی میکند.
سوالات متداول
Observable یک منبع سرد است: تا قبل از اشتراک رویدادها را منتشر نمیکند. Subject داغ است: رویدادها را مستقل از مشترکان منتشر میکند و امکان درج دستی مقادیر را از طریق onNext فراهم میکند. PublishSubject فقط رویدادهای جدید را منتقل میکند، BehaviorSubject — آخرین رویداد به علاوه موارد جدید.
DisposeBag تمام اشتراکهای Disposable را ذخیره میکند. هنگامی که DisposeBag تخصیصزدایی میشود (مثلاً هنگام بسته شدن ViewController)، تمام اشتراکهای ذخیره شده به طور خودکار لغو میشوند. این تضمین میکند که Observable دیگر رویدادی به شی UI از بین رفته ارسال نخواهد کرد.
اگر حداقل نسخه iOS 13+ است و تیم SwiftUI بلد است — Combine را انتخاب کنید. اگر پروژه از iOS 12 و پایینتر پشتیبانی میکند یا به مجموعه عملگرهای بزرگتری نیاز دارد — RxSwift. Combine یکپارچگی بهتری با Foundation (URLSession, Timer, NotificationCenter) فراهم میکند.
Schedulers رشتههای اجرا را انتزاع میکنند. subscribeOn مشخص میکند که اشتراک در کدام Scheduler انجام شود (معمولاً background). observeOn تعیین میکند که رویدادها در کدام Scheduler دریافت شوند (بیشتر MainScheduler برای بهروزرسانیهای UI). SerialDispatchQueueScheduler از طریق GCD کار میکند.
بله، RxSwift را میتوان از طریق ObservableObject با SwiftUI یکپارچه کرد. از BehaviorRelay به عنوان ویژگیهای @Published استفاده کنید: اشتراک در Relay تغییرات را به Combine منتقل میکند و SwiftUI View را از طریق @ObservedObject دوباره ترسیم میکند. این یک الگوی محبوب مهاجرت از UIKit به SwiftUI است.
خلاصه
ما یک اپلیکیشن موبایل به صورت کلید در دست توسعه خواهیم داد
IT Sectr از سال 2017 برنامههای iOS و Android را برای استارتاپها و کسبوکارها ایجاد میکند. ما به شما مشاوره میدهیم و بهترین راهحل را پیشنهاد خواهیم کرد.
همچنین بخوانید