Programación reactiva en Swift (iOS/macOS): Combine y RxSwift
La programación reactiva es un paradigma basado en el trabajo con flujos de datos asíncronos y la propagación de cambios. En el ecosistema de Apple para iOS y macOS, las herramientas principales son el framework nativo Combine (desde iOS 13/macOS 10.15) y la biblioteca de terceros RxSwift. Ambos permiten escribir código declarativo, conciso y fácilmente testeable, liberando al desarrollador del «callback hell» y de la compleja gestión del estado.
Conceptos principales
- Publisher (Publicador) — fuente de datos que puede enviar valores, finalización o error.
- Subscriber (Suscriptor) — recibe datos del Publisher y reacciona a ellos.
- Operator (Operador) — función de transformación del flujo (map, filter, combineLatest, debounce, etc.).
- Subject — híbrido que puede tanto recibir como enviar eventos (PassthroughSubject, CurrentValueSubject).
- Scheduler (Planificador) — determina en qué hilo se ejecuta el código.
Combine: framework nativo de Apple
Combine está integrado en Foundation y trabaja con Publisher y Subscriber. Ejemplo de uso para procesar un campo de texto:
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() // Creamos un Publisher desde 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() // Nos suscribimos publisher .sink { [weak self] value in self?.label.text = "Usted ingresó: \\(value)" } .store(in: &cancellables) }}En el ejemplo se usa debounce para retrasar la reacción a la entrada y removeDuplicates para ignorar valores repetidos.
RxSwift: potente alternativa
RxSwift es un puerto de ReactiveX para Swift. Ofrece un conjunto más amplio de operadores y soporta versiones anteriores de iOS. El mismo ejemplo con 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 = "Usted ingresó: \\(text)" }) .disposed(by: disposeBag) }}Observe el uso de rx.text (a través de RxCocoa) y distinctUntilChanged() — análogo de removeDuplicates en Combine.
Operadores clave
map/compactMap— transformación de valores.filter— solo deja pasar valores que cumplen una condición.combineLatest— combina los últimos valores de varios flujos.zip— combina por pares los elementos de varios flujos.flatMap— transforma un flujo en otro flujo (a menudo usado para solicitudes de red).catch/retry— manejo de errores.
También en la biblioteca
Generación de PDF en PHP: revisión de bibliotecas y ejemplos de código
Procesamiento JSON en Java: bibliotecas Jackson y Gson para trabajar con datos
Biblioteca WebSocket Gorilla para Go (Golang) — guía completa