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 се абонира за Observable чрез метода subscribe и получава тези събития. Този модел се нарича Reactive Streams и гарантира, че нито едно събитие няма да бъде загубено при правилен абонамент.
RxSwift предоставя над 300 оператора за работа с потоци: map трансформира всяко събитие, filter пропуска само подходящите, flatMap разгръща вложени Observable в един поток. Операторите се комбинират във вериги, създавайки декларативен тръбопровод за обработка на данни без странични ефекти.
Освен основния Observable, RxSwift предоставя специализирани типове обвивки. 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 се тества без UI чрез виртуални Scheduler-и.
RxSwift е подходящ както за малки проекти с няколко екрана, така и за големи enterprise приложения с десетки модули. В големи проекти реактивните вериги проникват в цялата архитектура: от наблюдение на UserDefaults чрез RxProperty до мрежови заявки чрез Moya (RxSwift обвивка над Alamofire). Всеки модул е изолиран и комуникира чрез реактивни интерфейси, което опростява замяната на имплементацията без промяна на абонатите. С правилна архитектура RxSwift намалява количеството код в сравнение с класическите подходи, тъй като не е необходимо да се пише boilerplate за 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 — това намалява риска от race condition. За мемоизация на Observable се използва операторът 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 повече няма да изпрати събитие на вече унищожен UI обект.
Ако минималната версия на iOS е 13+ и екипът познава SwiftUI — изберете Combine. Ако проектът поддържа iOS 12 и по-долу или изисква по-голям набор от оператори — RxSwift. Combine осигурява по-добра интеграция с Foundation (URLSession, Timer, NotificationCenter).
Schedulers абстрахират нишките на изпълнение. subscribeOn указва на кой Scheduler се изпълнява абонаментът (обикновено background). observeOn определя на кой Scheduler се приемат събитията (по-често MainScheduler за UI актуализации). SerialDispatchQueueScheduler работи чрез GCD.
Да, RxSwift може да бъде интегриран със SwiftUI чрез ObservableObject. Използвайте BehaviorRelay като @Published свойства: абонаментът към Relay предава промените на Combine, а SwiftUI прерисува View чрез @ObservedObject. Това е популярен модел за миграция от UIKit към SwiftUI.
Обобщение
Ще разработим мобилно приложение под ключ
IT Sectr създава iOS и Android приложения за стартъпи и бизнеси от 2017 г. Ще ви консултираме и ще предложим най-доброто решение.
Прочетете също