RxSwift egy reaktív programozási könyvtár iOS-hez, amely az Observable mintát és funkcionális operátorokat valósítja meg az aszinkron adatfolyamokkal való munkához. A ReactiveX (Rx) koncepcióit portolja Swift nyelvre, egységes API-t biztosítva az UI események, hálózati kérések, adatbázisok és időzítők kezeléséhez. A ReactiveX, 2025 adatai szerint a könyvtárat több mint 60 000 projekt használja GitHub-on, és a natív Combine megjelenésig a Swift reaktív programozásának szabványa marad. Az RxSwift a delegátumokat, lezárásokat és értesítéseket egységes eseményfeldolgozó lánccal helyettesíti.
Főbb pontok
RxSwift a ReactiveX (Rx) könyvtár Swift portja, amelyet a Microsoft készített .NET-hez 2012-ben. Az Rx fő gondolata — minden aszinkron adatforrást Observable szekvenciáként bemutatni, amelyre funkcionális operátorok alkalmazhatók. Az iOS fejlesztésben az RxSwift az UI események (gombnyomások, szövegbevitel, gesztusok) összekötésére szolgál az alkalmazás logikájával kifejezett delegátumok és target-action nélkül.
A könyvtár három modulból áll: RxSwift (mag — Observable, Operator, Scheduler), RxCocoa (integráció UIKit-kel — rx kiterjesztések UIButton, UITextField, UITableView számára) és RxRelay (Subject terminális események nélkül). Ez a felosztás lehetővé teszi a mag használatát szerver Swift-ben és tesztekben, az UI csatlakozót csak iOS alkalmazásokhoz kapcsolva.
A Stack Overflow, 2025 felmérése szerint az RxSwift a top 5 legtöbbet használt külső könyvtár közé tartozik iOS-hez. A népszerűség fő oka — az összes aszinkron minta egységes kezelése: hálózati kérések URLSession-en keresztül, animációk UIViewPropertyAnimator-on keresztül, értesítések NotificationCenter-en keresztül és delegátumok DelegateProxy-on keresztül — mindez Observable-re vezethető vissza kiszámítható életciklussal.
Reaktív programozás egy paradigma, amelyben a program reagál az adatok változásaira, ahelyett hogy lekérdezze azokat. Ahelyett, hogy úgy írna „adatok lekérése → feldolgozás → UI frissítése”, a fejlesztő egy átalakítási láncot ír le: ‚amikor az adatok megváltoznak, alkalmazz szűrőt, majd map-et, majd frissítsd az UI-t”. Az RxSwift ezt a paradigmát Observable láncokon keresztül valósítja meg lusta végrehajtással — semmi sem történik, amíg meg nem jelenik egy feliratkozó.
Observable az RxSwift alapvető típusa, amely események időbeli sorozatát reprezentálja. Az Observable három típusú eseményt küldhet: next (új érték), error (hiba, befejezi a folyamot) és completed (sikeres befejezés). Léteznek finite Observable (összes érték elküldése után befejeződik) és infinite Observable (pl. UI események — soha nem ér véget).
Életciklus az Observable három szakaszból áll: létrehozás (create, just, from), átalakítás (map, filter, flatMap operátorok) és feliratkozás (subscribe). Feliratkozás nélkül az Observable nem végez semmilyen műveletet — ez egy lusta szekvencia. Feliratkozás után az Observable eseményeket kezd küldeni a feliratkozónak, amíg be nem fejeződik, vagy a feliratkozó le nem mondja a feliratkozást a Disposable-en keresztül.
import RxSwift
// Observable létrehozása tömböd
let numbers = Observable.from([1, 2, 3, 4, 5])
// Átalakítás operátorokkal
let squared = numbers
.filter { $0 % 2 == 0 }
.map { $0 * $0 }
// Feliratkozás eseménykezeléssel
let disposable = squared
.subscribe(onNext: { print($0) },
onError: { print("Error: \($0)") },
onCompleted: { print("Done") })
Subject egy olyan típus, amely egyszerre Observable (fel lehet iratkozni rá) és Observer (eseményeket lehet küldeni bele). Az RxSwift négy típusú Subject-et kínál: PublishSubject (csak új események), BehaviorSubject (kezdeti értékkel), ReplaySubject (utolsó N esemény pufferelése) és AsyncSubject (csak az utolsó érték befejezés előtt). A Subject kényelmes az imperatív kód (lezárások, delegátumok) reaktív láncba történő integrálásához.
Disposable a feliratkozás lemondásának tokenje. Amikor a feliratkozó már nem akar eseményeket kapni, meghívja a disposable.dispose()-t. A gyakorlatban a DisposeBag-et használják: Disposable-ek gyűjteménye, amely automatikusan lemondja az összes feliratkozást a tulajdonos deinicializálásakor (pl. UIViewController). Ez megakadályozza a memóriaszivárgást, ami elkerülhetetlen a feliratkozások kézi kezelésekor.
| Subject típus | Kezdeti érték | Megismétli a feliratkozónak | Használat |
|---|---|---|---|
| PublishSubject | Nem | Csak új események | UI események, ritka értesítések |
| BehaviorSubject | Igen | Utolsó + új | Állapot, adatfolyam |
| ReplaySubject | Nem | Puffer N + új | Előzmények gyorsítótárazása |
| AsyncSubject | Nem | Csak utolsó | Számítási feladatok |
| PublishRelay | Nem | Csak új | Error/completed nélkül
Operátorok az RxSwift-ben olyan függvények, amelyek egy Observable-t vesznek és egy másik Observable-t adnak vissza, átalakítva az adatfolyamot. Az operátorok kombinálásával a fejlesztő deklaratív feldolgozó láncokat épít köztes változók és versenyhelyzetek nélkül. Minden operátor lusta: a lánc a leíráskor épül fel, és a feliratkozáskor hajtódik végre.
Átalakító operátorok megváltoztatják a folyam minden eseményét. A map függvényt alkalmaz minden elemre, a flatMap kicsomagolja az Observable-t minden elemből egyetlen sík folyammá, a scan felhalmozza a köztes eredményt (a reduce analógja, de minden lépés kibocsátásával). A buffer csoportosítja az elemeket idő vagy mennyiség szerint, a window folyamokat nested Observable-ekre osztja ablakonként.
// Példa operátor láncra: keresés debounce-szal
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)
Szűrő operátorok csak azokat az eseményeket engedik át, amelyek megfelelnek a feltételnek. A filter predikátum alapján szétválaszt, a distinctUntilChanged csak az előzőtől különböző értékeket engedi át, a take és takeWhile korlátozza az események számát. A skip és skipWhile kihagyja az első N eseményt vagy az eseményeket a feltétel teljesülésig. A hibakezeléshez a catchError (elfogás és helyettesítés) és retry (sorozat megismétlése hiba esetén) használható.
Kombináló operátorok több Observable-t egyesítenek eggyé. A combineLatest több folyamból az utolsó értékeket egyesíti egy tuple-be, a zip páronként kombinálja az azonos indexű elemeket, a merge több folyamot egyesít az események érkezési sorrendjében. A withLatestFrom egy eseményt a fő folyamból egy másik folyam utolsó értékével kombinál — kényelmes UI eseményekhez aktuális állapottal.
| Kategória | Operátor | Művelet |
|---|---|---|
| Átalakítás | map | Minden értéket függvényen keresztül alakít át |
| Átalakítás | flatMap | Kicsomagolja a beágyazott Observable-t sík folyammá |
| Szűrés | filter | Értékeket enged át predikátum alapján |
| Szűrés | distinctUntilChanged | Csak módosult értékeket enged át |
| Kombinálás | combineLatest | Egyesíti az utolsó értékeket 2+ folyamból |
| Kombinálás | zip | Páronként kombinálja az elemeket index szerint |
| Kezelés | debounce | Késlelteti az eseményeket a folyam szünetéig |
| Kezelés | take | Elveszi az első N eseményt és befejezi a folyamot |
Scheduler az RxSwift-ben egy absztrakció a végrehajtási szál (vagy sor) felett. A Scheduler meghatározza, hogy melyik szálon történik az események létrehozása, átalakítása és a feliratkozás. Ellentétben a GCD-vel, ahol a fejlesztő kifejezetten megadja a DispatchQueue-t, az RxSwift két paramétert használ: subscribeOn (melyik szálon fut az Observable) és observeOn (melyik szálon hívódik a feliratkozó).
MainScheduler a fő szálon hajtja végre a kódot — kötelező az UIKit frissítéséhez (minden UI változásnak a main thread-en kell történnie). A SerialDispatchQueueScheduler egy szekvenciális GCD sort csomagol be, a ConcurrentDispatchQueueScheduler egy párhuzamosat. Háttérfeladatokhoz a ConcurrentDispatchQueueScheduler használatos qos: .background vagy .utility paraméterrel.
// Tipikus minta: háttérmunka + UI main-en
apiService.fetchData()
.subscribeOn(ConcurrentDispatchQueueScheduler(qos: .background))
.observeOn(MainScheduler.instance)
.subscribe(onNext: { data in
self.tableView.reloadData()
self.loadingIndicator.stopAnimating()
})
.disposed(by: disposeBag)
A Scheduler helyes használata megakadályozza az UI blokkolását hálózati kérések és nehéz számítások során. A subscribeOn az egész upstream-re hat (minden operátor az observeOn-ig a megadott ütemezőn fut). Az observeOn váltja a downstream-t — minden operátor az observeOn után a megadott ütemezőn fut. A láncban több observeOn is lehet a szálak váltásához a transformáció különböző szakaszaiban.
RxSwift iOS projektekben leggyakrabban az UI és adatok összekapcsolására használják reaktív láncokon keresztül. Az RxCocoa rx kiterjesztéseket biztosít az összes szabványos UIKit komponenshez: rx.tap UIButton-hoz, rx.text UITextField-hez, rx.selectedRow UIPickerView-hez. Ez lehetővé teszi az @IBAction és delegátumok elhagyását, helyettesítve azokat deklaratív feliratkozásokkal.
MVVM (Model-View-ViewModel) egy architektúrai minta, amelyben a ViewModel kezeli az állapotot és üzleti logikát, a View pedig feliratkozik a ViewModel reaktív tulajdonságaira. Az RxSwift tökéletesen illeszkedik az MVVM-be: a ViewModel Observable-t vagy Driver-t tesz közzé az adatokhoz, a View feliratkozik rájuk bind segítségével. A ViewModel nem hivatkozik a View-ra — Observable-t ad vissza, amelyet a View fogyaszt.
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-ben:
viewModel.isFormValid
.bind(to: loginButton.rx.isEnabled)
.disposed(by: disposeBag)
Hálózati kérések — az RxSwift második leggyakoribb alkalmazási területe. Az URLSession.rx.response HTTP kérést csomagol Observable-be, amely sikernél (response, data), sikertelenségnél error értéket ad vissza. A Codable és map operátor kombinációjával kompakt reaktív API réteget kapunk: Observable<MyModel> callback-ek és hibakezelés nélkül minden metódusban. Hálózati hibánál a retry(3) operátor automatikusan háromszor megismétli a kérést exponenciális késleltetéssel.
Combine egy natív Apple keretrendszer, amelyet iOS 13-ban vezettek be. Ugyanazokat a feladatokat oldja meg, mint az RxSwift: aszinkron eseményekkel való munka Publisher, Subscriber és operátorok segítségével. A Combine-nak azonban kulcsfontosságú különbségei vannak: a hibák szigorú típusosztálya a Failure típuson keresztül, beépített támogatás a Swift Concurrency-hez (async/await) és integráció a SwiftUI-val @Published és ObservableObject segítségével.
RxSwift a visszafelé kompatibilitásban nyer — támogatja az iOS 8+-t, míg a Combine iOS 13+-t igényel. Az RxSwift gazdagabb külső kiterjesztési ökoszisztémával rendelkezik (RxDataSources, RxGesture, RxAnimated) és részletes operátor dokumentációval. Az iOS régebbi verzióit támogató projektek számára az RxSwift marad az egyetlen választás.
Új iOS 13+ projektekhez az Apple a Combine-t ajánlja. Szorosan integrálódik a SwiftUI-val, kisebb bináris mérettel és hivatalos támogatással rendelkezik. Azonban a meglévő RxSwift kód Combine-ba migrálása az összes Observable → Publisher átírását igényli, és az RxCocoa ökoszisztémának nincs teljes megfelelője Combine-ban — az UIKit nem rendelkezik natív Publisher-rel az összes UI komponenshez.
| Jellemző | RxSwift | Combine |
|---|---|---|
| Minimális iOS | iOS 8+ | iOS 13+ |
| Hiba típusa | Error (bármilyen) | Generic Failure |
| UI kiterjesztések | RxCocoa (UIKit, AppKit) | @Published (SwiftUI) |
| Operátorok | 400+ operátor | ~100 operátor |
| Swift Concurrency | Hídon keresztül | Natív támogatás |
| Státusz | Külső | Hivatalos Apple |
Gyakran Ismételt Kérdések
Observable eseményforrás lusta végrehajtással. A Subject egyszerre Observable és Observer — fel lehet iratkozni rá és kézzel új eseményeket küldeni bele. A Subject kényelmes az imperatív kód reaktív láncokba történő integrálásához.
RxSwift akkor választandó, ha iOS 11-12 támogatásra van szükség, létezik RxSwift kódbázis, vagy gazdag operátor ökoszisztémára van szükség (400+ vs ~100 Combine-ban). Új iOS 13+ projektekhez a Combine ajánlott.
DisposeBag Disposable tokenek gyűjteménye, amely automatikusan lemondja az összes feliratkozást a tulajdonos deinicializálásakor. DisposeBag nélkül a feliratkozás erős hivatkozást hoz létre a lezárásra, ami memóriaszivárgáshoz vezet a UIViewController megsemmisülésekor.
Használja a catchError-t a hiba alapértelmezett értékkel való helyettesítéséhez, a retry-t az Observable újrafuttatásához, a materialize-t a hiba eseménnyé alakításához. Az UI rétegben a Driver és Signal nem továbbítja a hibákat — azok belsőleg kerülnek kezelésre.
Driver egy speciális Observable típus, amely garantálja a MainScheduler-en történő végrehajtást, a hibák hiányát és az erőforrások megosztását. A Driver garantálja, hogy az UI frissítések a fő szálon történjenek. Az Observable nem nyújt ilyen garanciákat — observeOn szükséges.
Összefoglalás
Kulcsrakész mobilalkalmazást fejlesztünk
Az IT Sectr 2017 óta készít iOS és Android alkalmazásokat induló vállalkozásoknak és vállalkozásoknak. Tanácsot adunk, és a legjobb megoldást javasoljuk.
Olvassa el is