RxSwift, Observable desenini ve işlevsel operatörleri uygulayarak asenkron veri akışlarıyla çalışmak için iOS için bir reaktif programlama kütüphanesidir. ReactiveX (Rx) kavramlarını Swift diline taşıyarak UI, ağ istekleri, veritabanları ve zamanlayıcılardan gelen olayları işlemek için birleşik bir API sağlar. ReactiveX, 2025'e göre kütüphane, GitHub'da 60.000'den fazla projede kullanılmaktadır ve yerel Combine'ın ortaya çıkışına kadar Swift'te reaktif programlamanın standardı olmaya devam etmektedir. RxSwift, delegeleri, closure'ları ve bildirimleri tek bir olay işleme zinciriyle değiştirir.
Önemli Noktalar
RxSwift, Microsoft tarafından 2012 yılında .NET için oluşturulan ReactiveX (Rx) kütüphanesinin Swift portudur. Rx'in temel fikri, herhangi bir asenkron veri kaynağını, işlevsel operatörlerin uygulanabileceği bir Observable dizisi olarak temsil etmektir. iOS geliştirmede RxSwift, UI olaylarını (düğme tıklamaları, metin girişi, jestler) açık delegeler ve target-action olmadan uygulama mantığına bağlamak için kullanılır.
Kütüphane üç modülden oluşur: RxSwift (çekirdek — Observable, Operator, Scheduler), RxCocoa (UIKit entegrasyonu — UIButton, UITextField, UITableView için rx uzantıları) ve RxRelay (terminal olayları olmayan Subject). Bu ayrım, çekirdeğin sunucu tarafı Swift ve testlerde kullanılmasına izin verirken, UI sarmalayıcısını yalnızca iOS uygulamaları için bağlar.
Stack Overflow, 2025 anketine göre RxSwift, iOS için en çok kullanılan ilk 5 üçüncü taraf kütüphanesi arasındadır. Popülerliğinin ana nedeni, tüm asenkron desenlerin tek tip işlenmesidir: URLSession ile ağ istekleri, UIViewPropertyAnimator ile animasyonlar, NotificationCenter ile bildirimler ve DelegateProxy ile delegeler — tüm bunlar öngörülebilir bir yaşam döngüsüne sahip bir Observable'a indirgenir.
Reaktif programlama, programın verileri yoklamak yerine veri değişikliklerine tepki verdiği bir paradigmadır. “Veri al → işle → UI'ı güncelle” yazmak yerine, geliştirici bir dönüşüm zinciri tanımlar: “veri değiştiğinde, filtre uygula, sonra map, sonra UI'ı güncelle”. RxSwift bu paradigmayı tembel yürütmeli Observable zincirleri aracılığıyla uygular — bir abone görünene kadar hiçbir şey olmaz.
Observable, zaman içindeki olay dizisini temsil eden temel RxSwift türüdür. Observable üç tür olay gönderebilir: next (yeni değer), error (akışı sonlandıran hata) ve completed (başarılı tamamlama). Sonlu Observable (tüm değerleri gönderdikten sonra tamamlanır) ve sonsuz Observable (örneğin UI olayları — asla tamamlanmaz) vardır.
Bir Observable'ın yaşam döngüsü üç aşamayı içerir: oluşturma (create, just, from), dönüştürme (map, filter, flatMap operatörleri) ve abonelik (subscribe). Abonelik olmadan Observable hiçbir işlem yapmaz — tembel bir dizidir. Abonelikten sonra Observable, tamamlanana veya abone Disposable aracılığıyla aboneliği iptal edene kadar aboneye olay göndermeye başlar.
import RxSwift
// Diziden Observable oluşturma
let numbers = Observable.from([1, 2, 3, 4, 5])
// Operatörler aracılığıyla dönüştürme
let squared = numbers
.filter { $0 % 2 == 0 }
.map { $0 * $0 }
// Olay işlemeli abonelik
let disposable = squared
.subscribe(onNext: { print($0) },
onError: { print("Error: \($0)") },
onCompleted: { print("Done") })
Subject, hem Observable (abone olunabilir) hem de Observer (olay gönderilebilir) olan bir türdür. RxSwift dört tür Subject sağlar: PublishSubject (yalnızca yeni olaylar), BehaviorSubject (başlangıç değeriyle), ReplaySubject (son N olayı arabelleğe alır) ve AsyncSubject (tamamlanmadan önce yalnızca son değer). Subject, imperatif kodu (closure'lar, delegeler) reaktif bir zincire entegre etmek için kullanışlıdır.
Disposable, abonelik iptal belirtecidir. Abone artık olay almak istemediğinde disposable.dispose() çağrısını yapar. Pratikte DisposeBag kullanılır: sahibinin (örneğin UIViewController) ilklendirmesi kaldırıldığında tüm abonelikleri otomatik olarak iptal eden bir Disposable koleksiyonu. Bu, manuel abonelik yönetiminde kaçınılmaz olan bellek sızıntılarını önler.
| Subject Türü | Başlangıç Değeri | Aboneye Tekrar Gönderir | Kullanım |
|---|---|---|---|
| PublishSubject | Hayır | Yalnızca yeni olaylar | UI olayları, nadir bildirimler |
| BehaviorSubject | Evet | Son + yeni | Durum, veri akışı |
| ReplaySubject | Hayır | Arabellek N + yeni | Geçmiş önbellekleme |
| AsyncSubject | Hayır | Yalnızca son | Hesaplama görevleri |
| PublishRelay | Hayır | Yalnızca yeni | Hata/tamamlama yok |
RxSwift'teki operatörler, bir Observable alan ve veri akışını dönüştürerek başka bir Observable döndüren işlevlerdir. Operatörleri birleştirerek geliştirici, ara değişkenler ve yarış koşulları olmadan bildirimsel işleme zincirleri oluşturur. Tüm operatörler tembeldir: zincir tanımlama sırasında oluşturulur ve abonelikte yürütülür.
Dönüştürme operatörleri akıştaki her olayı değiştirir. map her öğeye bir işlev uygular, flatMap her öğeden Observable'ı tek bir düz akışa açar, scan ara sonuçları biriktirir (reduce'a benzer ancak her adımı yayar). buffer öğeleri zamana veya sayıya göre gruplandırır, window akışı pencerelere göre iç içe Observable'lara böler.
// Operatör zinciri örneği: debounce ile arama
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)
Filtreleme operatörleri yalnızca bir koşulu karşılayan olayların geçmesine izin verir. filter yüklemle filtreler, distinctUntilChanged yalnızca öncekinden farklı değerleri geçirir, take ve takeWhile olay sayısını sınırlar. skip ve skipWhile ilk N olayı veya bir koşul sağlanana kadar olayları atlar. Hata işleme için catchError (yakalama ve değiştirme) ve retry (hata durumunda diziyi yeniden dene) kullanılır.
Birleştirme operatörleri birden çok Observable'ı birleştirir. combineLatest birden çok akıştaki son değerleri bir demet halinde birleştirir, zip aynı dizine sahip öğeleri eşleştirir, merge birden çok akışı olay geliş sırasına göre birleştirir. withLatestFrom ana akıştaki bir olayı başka bir akıştaki son değerle birleştirir — mevcut durumla UI olayları için kullanışlıdır.
| Kategori | Operatör | Açıklama |
|---|---|---|
| Dönüştürme | map | Her değeri bir işlev aracılığıyla dönüştürür |
| Dönüştürme | flatMap | İç içe Observable'ları düz bir akışa açar |
| Filtreleme | filter | Değerleri yüklemle geçirir |
| Filtreleme | distinctUntilChanged | Yalnızca değişen değerleri geçirir |
| Birleştirme | combineLatest | 2+ akıştaki son değerleri birleştirir |
| Birleştirme | zip | Öğeleri dizine göre eşleştirir |
| Kontrol | debounce | Akışta duraklamaya kadar olayları geciktirir |
| Kontrol | take | İlk N olayı alır ve akışı tamamlar |
RxSwift'teki Scheduler, yürütme iş parçacığı (veya kuyruğu) üzerinde bir soyutlamadır. Scheduler, olay oluşturma, dönüştürme ve aboneliğin hangi iş parçacığında yürütüleceğini belirler. Geliştiricinin açıkça DispatchQueue belirttiği GCD'nin aksine RxSwift iki parametre kullanır: subscribeOn (Observable'ın hangi iş parçacığında yürütüleceği) ve observeOn (abonenin hangi iş parçacığında çağrılacağı).
MainScheduler kodu ana iş parçacığında yürütür — UIKit güncellemeleri için zorunludur (tüm UI değişiklikleri ana iş parçacığında gerçekleşmelidir). SerialDispatchQueueScheduler seri bir GCD kuyruğunu sarar, ConcurrentDispatchQueueScheduler eşzamanlı bir kuyruğu sarar. Arka plan görevleri için qos: .background veya .utility ile ConcurrentDispatchQueueScheduler kullanılır.
// Tipik desen: arka plan işi + main'de UI
apiService.fetchData()
.subscribeOn(ConcurrentDispatchQueueScheduler(qos: .background))
.observeOn(MainScheduler.instance)
.subscribe(onNext: { data in
self.tableView.reloadData()
self.loadingIndicator.stopAnimating()
})
.disposed(by: disposeBag)
Scheduler'ın doğru kullanımı, ağ istekleri ve ağır hesaplamalar sırasında UI blokajını önler. subscribeOn tüm yukarı akışı etkiler (observeOn'dan önceki tüm operatörler belirtilen zamanlayıcıda yürütülür). observeOn aşağı akışı değiştirir — observeOn'dan sonraki tüm operatörler belirtilen zamanlayıcıda yürütülür. Bir zincirde, farklı dönüştürme aşamalarında iş parçacıkları arasında geçiş yapmak için birden çok observeOn bulunabilir.
SerialDispatchQueueScheduler, paylaşılan kaynakların iş parçacığı güvenliği için önemli olan sıralı olay işlemeyi garanti eder. Yüksek yük operasyonları (görüntü işleme, JSON ayrıştırma) için ConcurrentDispatchQueueScheduler kullanın — RxSwift bir Observable içinde olay sırasını koruyacaktır, ancak farklı Observable'lar paralel olarak işlenebilir.
RxSwift iOS projelerinde en sık reaktif zincirler aracılığıyla UI'ı verilere bağlamak için kullanılır. RxCocoa, tüm standart UIKit bileşenleri için rx uzantıları sağlar: UIButton için rx.tap, UITextField için rx.text, UIPickerView için rx.selectedRow. Bu, @IBAction ve delegelerden vazgeçerek bunların yerine bildirimsel abonelikler koymayı sağlar.
MVVM (Model-View-ViewModel), ViewModel'in durumu ve iş mantığını yönettiği ve View'in ViewModel'in reaktif özelliklerine abone olduğu bir mimari desendir. RxSwift MVVM ile mükemmel uyum sağlar: ViewModel veri için Observable veya Driver yayınlar, View bunlara bind aracılığıyla abone olur. ViewModel'in View'a referansı yoktur — View'in tükettiği Observable'ları döndürür.
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'da:
viewModel.isFormValid
.bind(to: loginButton.rx.isEnabled)
.disposed(by: disposeBag)
Ağ istekleri, RxSwift'in ikinci en yaygın kullanım durumudur. URLSession.rx.response, HTTP isteğini bir Observable'a sarar ve başarı durumunda (response, data) veya başarısızlık durumunda error döndürür. Codable ve map operatörüyle birleştiğinde, kompakt bir reaktif API katmanı elde edilir: geri aramalar ve her yöntemde hata işleme olmadan Observable<MyModel>. Ağ hatasında, retry(3) operatörü üstel geri alma ile isteği otomatik olarak üç kez yeniden dener.
Combine, iOS 13'te tanıtılan Apple'ın yerel framework'üdür. RxSwift ile aynı görevleri çözer: Publisher, Subscriber ve operatörler aracılığıyla asenkron olaylarla çalışmak. Ancak Combine'ın temel farklılıkları vardır: Failure türü aracılığıyla katı hata tiplemesi, Swift Concurrency (async/await) için yerleşik destek ve @Published ve ObservableObject aracılığıyla SwiftUI ile entegrasyon.
RxSwift geriye dönük uyumlulukta kazanır — iOS 8+'ı desteklerken, Combine iOS 13+ gerektirir. RxSwift daha zengin bir üçüncü taraf uzantı ekosistemine (RxDataSources, RxGesture, RxAnimated) ve ayrıntılı operatör dokümantasyonuna sahiptir. Eski iOS sürümlerini destekleyen projeler için RxSwift tek seçenek olarak kalır.
iOS 13+ ile yeni projeler için Apple Combine'ı önerir. SwiftUI ile sıkı bir şekilde entegredir, daha küçük ikili boyuta ve resmi desteğe sahiptir. Ancak, mevcut RxSwift kodunu Combine'a taşımak tüm Observable → Publisher'ları yeniden yazmayı gerektirir ve RxCocoa ekosisteminin tam bir Combine karşılığı yoktur — UIKit'in tüm UI bileşenleri için yerel Publisher'ı yoktur.
| Özellik | RxSwift | Combine |
|---|---|---|
| Minimum iOS | iOS 8+ | iOS 13+ |
| Hata Türü | Error (herhangi) | Generic Failure |
| UI Uzantıları | RxCocoa (UIKit, AppKit) | @Published (SwiftUI) |
| Operatörler | 400+ operatör | ~100 operatör |
| Swift Concurrency | Köprü aracılığıyla | Yerel destek |
| Durum | Üçüncü taraf | Apple resmi |
Sıkça Sorulan Sorular
Observable tembel yürütmeli olay kaynağıdır. Subject hem Observable hem de Observer'dır — abone olabilir ve manuel olarak yeni olaylar gönderebilirsiniz. Subject, imperatif kodu reaktif zincirlere entegre etmek için kullanışlıdır.
RxSwift, iOS 11-12 desteği gerektiğinde, mevcut bir RxSwift kod tabanı olduğunda veya zengin bir operatör ekosistemi gerektiğinde (Combine'daki ~100'e karşı 400+) seçilir. iOS 13+ üzerindeki yeni projeler için Combine tercih edilir.
DisposeBag, sahibinin ilklendirmesi kaldırıldığında tüm abonelikleri otomatik olarak iptal eden bir Disposable belirteç koleksiyonudur. DisposeBag olmadan abonelik, closure'a güçlü bir referans oluşturur ve UIViewController yok edildiğinde bellek sızıntısına yol açar.
Bir hatayı varsayılan değerle değiştirmek için catchError, Observable yürütmesini yeniden denemek için retry, hatayı bir olaya dönüştürmek için materialize kullanın. UI katmanında Driver ve Signal hata iletmez — dahili olarak işlenirler.
Driver, MainScheduler'da yürütmeyi, hata olmamasını ve kaynak paylaşımını garanti eden özel bir Observable türüdür. Driver, UI güncellemelerinin ana iş parçacığında gerçekleşmesini sağlar. Observable bu tür garantiler sağlamaz — observeOn gereklidir.
Özet
Anahtar teslim bir mobil uygulama geliştireceğiz
IT Sectr, 2017'den beri girişimler ve işletmeler için iOS ve Android uygulamaları oluşturmaktadır. Size danışmanlık yapacak ve en iyi çözümü önereceğiz.
Ayrıca okuyun