Reactive Programming in Swift: Combine and RxSwift for iOS/macOS

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Reactive Programming in Swift (iOS/macOS): Combine and RxSwift

Reactive programming is a paradigm based on working with asynchronous data streams and propagating changes. In the Apple ecosystem for iOS and macOS, the main tools are the native Combine framework (since iOS 13/macOS 10.15) and the third-party library RxSwift. Both allow writing declarative, concise, and easily testable code, freeing the developer from "callback hell" and complex state management.



Basic Concepts

  • Publisher — a data source that can send values, completion, or an error.
  • Subscriber — receives data from the Publisher and reacts to it.
  • Operator — a stream transformation function (map, filter, combineLatest, debounce, etc.).
  • Subject — a hybrid that can both receive and send events (PassthroughSubject, CurrentValueSubject).
  • Scheduler — determines on which thread the code executes.


Combine: Native Apple Framework

Combine is built into Foundation and works with Publisher and Subscriber. Example of use for handling a text field:

import Combineimport UIKit

class ViewController: UIViewController { @IBOutlet weak var textField: UITextField! @IBOutlet weak var label: UILabel! private var cancellables = Set<AnyCancellable>()

override func viewDidLoad() { super.viewDidLoad() // Create a Publisher from NotificationCenter let publisher = NotificationCenter.default .publisher(for: UITextField.textDidChangeNotification, object: textField) .compactMap { ($0.object as? UITextField)?.text } .debounce(for: .milliseconds(500), scheduler: RunLoop.main) .removeDuplicates() // Subscribe publisher .sink { [weak self] value in self?.label.text = "You entered: \\(value)" } .store(in: &cancellables) }}

In the example, debounce is used to delay the reaction to input and removeDuplicates to ignore duplicate values.



RxSwift: Powerful Alternative

RxSwift is a port of ReactiveX for Swift. It offers a wider set of operators and supports older iOS versions. The same example with RxSwift:

import RxSwiftimport RxCocoa

class ViewController: UIViewController { @IBOutlet weak var textField: UITextField! @IBOutlet weak var label: UILabel! private let disposeBag = DisposeBag()

override func viewDidLoad() { super.viewDidLoad() textField.rx.text .orEmpty .debounce(.milliseconds(500), scheduler: MainScheduler.instance) .distinctUntilChanged() .subscribe(onNext: { [weak self] text in self?.label.text = "You entered: \\(text)" }) .disposed(by: disposeBag) }}

Note the use of rx.text (via RxCocoa) and distinctUntilChanged() — the equivalent of removeDuplicates in Combine.



Key Operators

Recommendations