RxSwift — що це, можливості та реактивне програмування

Автор: IT Sectr Опубліковано: 2026-05-03 Час читання: 10 хв

RxSwift — це бібліотека реактивного програмування для iOS, яка реалізує патерн Observable та функціональні оператори для роботи з асинхронними потоками даних. Вона портує концепції ReactiveX (Rx) на мову Swift, надаючи єдиний API для обробки подій від UI, мережевих запитів, БД та таймерів. За даними 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 використовується для зв'язування UI-подій (натискання кнопок, введення тексту, жести) з логікою додатка без явних делегатів та target-action.

Бібліотека складається з трьох модулів: RxSwift (ядро — Observable, Operator, Scheduler), RxCocoa (інтеграція з UIKit — rx-розширення для UIButton, UITextField, UITableView) та RxRelay (Subject без термінальних подій). Такий поділ дозволяє використовувати ядро в серверному Swift та тестах, підключаючи UI-обв'язку тільки для iOS-додатків.

Згідно з опитуванням Stack Overflow, 2025, RxSwift входить до топ-5 найбільш використовуваних сторонніх бібліотек для iOS. Основна причина популярності — одноманітна обробка всіх асинхронних патернів: мережеві запити через URLSession, анімації через UIViewPropertyAnimator, сповіщення через NotificationCenter та делегати через DelegateProxy — все це зводиться до Observable з передбачуваним життєвим циклом.

Філософія реактивного програмування

Реактивне програмування — це парадигма, в якій програма реагує на зміни даних, а не опитує їх. Замість того щоб писати «отримати дані → обробити → оновити UI», розробник описує ланцюжок трансформацій: «коли дані зміняться, застосувати фільтр, потім map, потім оновити UI». RxSwift реалізує цю парадигму через Observable ланцюжки з лінивим виконанням — нічого не відбувається, поки не з'явиться підписник.

Ключові компоненти RxSwift: Observable, Subject, Disposable

Observable — фундаментальний тип RxSwift, що представляє послідовність подій у часі. Observable може надсилати три типи подій: next (нове значення), error (помилка, що завершує потік) та completed (успішне завершення). Існують finite Observable (завершуються після надсилання всіх значень) та infinite Observable (наприклад, UI-події — ніколи не завершуються).

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НіТільки нові подіїUI-події, рідкісні сповіщення
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 (повтор послідовності при помилці).

Оператори комбінування об'єднують кілька Observable в один. combineLatest об'єднує останні значення з кількох потоків у кортеж, zip попарно комбінує елементи з однаковими індексами, merge об'єднує кілька потоків в один у порядку надходження подій. withLatestFrom комбінує подію з основного потоку з останнім значенням з іншого потоку — зручно для UI-подій з поточним станом.

КатегоріяОператорЩо робить
ТрансформаціяmapПеретворює кожне значення через функцію
ТрансформаціяflatMapРозгортає вкладені Observable у плаский потік
ФільтраціяfilterПропускає значення за предикатом
ФільтраціяdistinctUntilChangedПропускає тільки змінені значення
КомбінуванняcombineLatestОб'єднує останні значення з 2+ потоків
КомбінуванняzipПопарно комбінує елементи за індексом
КеруванняdebounceЗатримує події до паузи в потоці
КеруванняtakeБере перші N подій та завершує потік

Schedulers та керування потоками виконання

Scheduler в RxSwift — це абстракція над потоком виконання (або чергою). Scheduler визначає, на якому потоці виконується створення подій, трансформація та підписка. На відміну від GCD, де розробник явно вказує DispatchQueue, RxSwift використовує два параметри: subscribeOn (на якому потоці виконується Observable) та observeOn (на якому потоці викликається підписник).

MainScheduler та BackgroundScheduler

MainScheduler виконує код на головному потоці — обов'язковий для оновлення UIKit (всі UI-зміни повинні відбуватися на головному потоці). SerialDispatchQueueScheduler обгортає послідовну GCD-чергу, ConcurrentDispatchQueueScheduler — паралельну. Для фонових завдань використовується ConcurrentDispatchQueueScheduler з qos: .background або .utility.

swift
// Типовий патерн: фонова робота + UI на main
apiService.fetchData()
    .subscribeOn(ConcurrentDispatchQueueScheduler(qos: .background))
    .observeOn(MainScheduler.instance)
    .subscribe(onNext: { data in
        self.tableView.reloadData()
        self.loadingIndicator.stopAnimating()
    })
    .disposed(by: disposeBag)

Правильне використання Scheduler запобігає блокуванню UI при мережевих запитах та важких обчисленнях. subscribeOn впливає на весь upstream (всі оператори до observeOn виконуються на вказаному планувальнику). observeOn перемикає downstream — всі оператори після observeOn виконуються на вказаному планувальнику. У ланцюжку може бути кілька observeOn для перемикання між потоками на різних етапах трансформації.

SerialDispatchQueueScheduler гарантує послідовну обробку подій, що важливо для потокобезпеки спільних ресурсів. Для високонавантажених операцій (обробка зображень, парсинг JSON) використовуйте ConcurrentDispatchQueueScheduler — RxSwift збереже порядок подій всередині одного Observable, але різні Observable можуть оброблятися паралельно.

Практичне застосування RxSwift в iOS

RxSwift в iOS-проєктах найчастіше застосовується для зв'язування UI з даними через реактивні ланцюжки. 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> без callback-ів та обробки помилок у кожному методі. При помилці мережі оператор retry(3) автоматично повторює запит тричі з експоненційною затримкою.

RxSwift vs 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 для всіх UI-компонентів.

ХарактеристикаRxSwiftCombine
Мінімальна iOSiOS 8+iOS 13+
Тип помилкиError (будь-яка)Generic Failure
UI-розширенняRxCocoa (UIKit, AppKit)@Published (SwiftUI)
Оператори400+ операторів~100 операторів
Swift ConcurrencyЧерез містНативна підтримка
СтатусСтороння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 для перетворення помилки на подію. У UI-шарі Driver та Signal не передають помилки — вони обробляються всередині.

Чим Driver відрізняється від Observable в RxCocoa?

Driver — це спеціальний тип Observable, що гарантує виконання на MainScheduler, відсутність помилок та спільне використання ресурсів. Driver гарантує, що UI-оновлення відбуваються на головному потоці. Observable не дає таких гарантій — потрібен observeOn.

Підсумки

  • RxSwift — бібліотека реактивного програмування для iOS, що реалізує Observable-патерн та 400+ операторів трансформації
  • Observable, Subject, Disposable — три фундаментальні типи, що утворюють основу всіх реактивних ланцюжків
  • Оператори map, flatMap, filter, combineLatest, debounce дозволяють будувати декларативні ланцюжки без стану гонок
  • Schedulers (subscribeOn / observeOn) керують потоками виконання, запобігаючи блокуванню UI
  • RxCocoa надає rx-розширення для UIKit, замінюючи делегати та target-action реактивними підписками
  • Combine — нативна альтернатива від Apple для iOS 13+, але RxSwift залишається актуальним для старіших версій

Ми розробимо мобільний застосунок під ключ

IT Sectr створює застосунки для iOS та Android для стартапів і бізнесу з 2017 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.

Обговорити проект

Читайте також