RxSwift est une bibliothèque de programmation réactive pour Swift qui implémente le pattern Observable. Selon ReactiveX, 2025, c'est l'implémentation la plus populaire de Reactive Extensions pour l'écosystème Apple. Observable agit comme une source d'événements, tandis qu'Observer s'abonne pour les recevoir.
Points clés
RxSwift est une bibliothèque de programmation réactive pour le langage Swift, portée depuis Reactive Extensions (Rx). Elle permet de décrire des programmes asynchrones et orientés événements via Observable Sequence — une séquence de données disponibles dans le temps. Les développeurs iOS utilisent RxSwift pour gérer les requêtes réseau, les événements UI et les données en streaming sans callbacks imbriqués.
La base de RxSwift repose sur deux protocoles clés : ObservableType — une source d'événements qui peut émettre trois types de signaux : .next(value), .error(error) et .completed. Observer s'abonne à Observable via la méthode subscribe et reçoit ces événements. Ce modèle est appelé Reactive Streams et garantit qu'aucun événement n'est perdu avec un abonnement correct.
RxSwift fournit plus de 300 opérateurs pour travailler avec les flux : map transforme chaque événement, filter ne laisse passer que les événements correspondants, flatMap déplie les Observables imbriqués en un seul flux. Les opérateurs sont chaînés, créant un pipeline déclaratif de traitement des données sans effets secondaires.
En plus de l'Observable de base, RxSwift fournit des types wrapper spécialisés. Single émet exactement une valeur ou une erreur — idéal pour les requêtes HTTP. Completable se termine par un succès ou une échec sans valeur — pour les opérations d'écriture. Maybe combine les deux scénarios : peut se terminer avec une valeur, sans valeur ou avec une erreur. Ces Traits simplifient la sémantique et rendent le code auto-documenté.
La programmation réactive dans RxSwift est construite sur le pattern Observer. ObservableSequence est analogue à Sequence de la bibliothèque standard, mais avec un accès asynchrone aux éléments. Le flux d'événements est passé à travers une chaîne d'opérateurs, chacun retournant une nouvelle ObservableSequence sans muter l'originale.
Les opérateurs dans RxSwift sont des fonctions pures qui prennent une ObservableSequence et en retournent une nouvelle. Par exemple, map crée une nouvelle séquence en appliquant une transformation à chaque élément. En combinant les opérateurs, le développeur construit un pipeline où les données traversent toutes les étapes de traitement sans variables intermédiaires.
Schedulers sont une abstraction sur les threads d'exécution dans RxSwift. Un Scheduler détermine sur quel thread le code sera exécuté : MainScheduler — le thread UI, SerialDispatchQueueScheduler — une file d'arrière-plan. Les opérateurs subscribeOn et observeOn spécifient respectivement où le travail est effectué et où les résultats sont traités.
RxSwift inclut plusieurs types de base, chacun résolvant sa propre tâche dans le pipeline réactif. Single est un Observable qui émet exactement une valeur ou une erreur, pratique pour les requêtes réseau. Completable se termine par un succès ou un échec sans valeur. Maybe combine les propriétés de Single et Completable.
Subject est un Observable chaud qui agit également comme Observer. PublishSubject émet uniquement les nouveaux événements aux abonnés, BehaviorSubject — le dernier événement plus les nouveaux. Relay est une variante de Subject qui n'émet pas .error ou .completed, garantissant la continuité du flux. BehaviorRelay stocke la valeur actuelle et convient aux UI pilotées par l'état.
DisposeBag est une collection de Disposables qui annule automatiquement tous les abonnements lors de sa désallocation. Dans iOS, DisposeBag est généralement ajouté à UIViewController ou UIView. Lorsque l'écran est fermé, DisposeBag est nettoyé — cela évite les fuites mémoire et l'accès à des éléments UI inexistants.
Voici un exemple de création d'un Observable à partir d'un tableau de données en utilisant l'opérateur map pour transformer des chaînes :
let observable = Observable.of("Swift", "RxSwift", "Reactive")
observable
.map { $0.uppercased() }
.subscribe(onNext: { value in
print("Received: \(value)")
})
.disposed(by: disposeBag)
Le deuxième exemple montre la combinaison de deux requêtes réseau en utilisant zip — l'opérateur attend que les deux Observables émettent une valeur et combine les résultats en un tuple :
let first = fetchUser(id: "123")
let second = fetchPosts(userId: "123")
Observable
.zip(first, second)
.observe(on: MainScheduler.instance)
.subscribe(onNext: { user, posts in
updateUI(user: user, posts: posts)
})
.disposed(by: disposeBag)
Le troisième exemple montre l'utilisation de BehaviorRelay pour stocker l'état et mettre à jour automatiquement l'UI lors des changements : chaque modification state.accept() est immédiatement transmise aux abonnés, ce qui est idéal pour les patterns d'état dans l'architecture MVVM.
let state = BehaviorRelay(value: "idle")
state
.subscribe(onNext: { status in
print("Status: \(status)")
})
.disposed(by: disposeBag)
state.accept("loading") // Prints: Status: loading
RxSwift diffère des méthodes asynchrones traditionnelles (Delegation, NotificationCenter, Callback) par sa nature déclarative et sa composabilité. Contrairement à Combine, RxSwift supporte iOS 9+ et possède plus d'opérateurs. Cependant, Combine est intégré à Foundation et SwiftUI au niveau du langage, ce qui lui donne un avantage dans les nouveaux projets Apple.
Le principal avantage de RxSwift par rapport à GCD (Grand Central Dispatch) est la capacité à combiner et transformer des flux de données au niveau d'abstraction, plutôt que de gérer manuellement les files d'attente. Cependant, RxSwift nécessite l'apprentissage de concepts réactifs, ce qui augmente la barrière d'entrée pour l'équipe.
En pratique, RxSwift est utilisé dans les grands projets où les chaînes réactives connectent les événements UI, la logique métier et l'interaction réseau dans un seul pipeline. Par exemple, dans les applications de trading, les flux de cotations sont traités via RxSwift : les ticks arrivent du WebSocket, passent par le filtrage, sont regroupés par timeframe et affichés sur un graphique en temps réel. Ce scénario est difficile à implémenter via Delegation ou NotificationCenter sans perdre en lisibilité.
Les alternatives à RxSwift incluent Combine (iOS 13+), AsyncSequence de Swift Concurrency (iOS 15+), ainsi que des bibliothèques tierces comme ReactiveSwift sans lien avec les plateformes Apple. Le choix dépend de la version iOS minimale supportée et de l'expérience des développeurs. Pour les nouveaux projets iOS 15+, les équipes choisissent souvent AsyncSequence — il ne nécessite pas d'installation de bibliothèque et utilise les constructions natives du langage Swift.
Les patterns architecturaux avec RxSwift suivent généralement MVVM ou Clean Architecture. ViewModel contient toute la logique métier sous forme de chaînes Observable, View s'abonne aux données transformées. Le pattern Input-Output sépare les événements d'entrée (touchers, saisie de texte) des états de sortie (texte du bouton, visibilité du loader). Cette approche simplifie les tests : ViewModel est testé sans UI via des Schedulers virtuels.
RxSwift convient aussi bien aux petits projets avec quelques écrans qu'aux grandes applications d'entreprise avec des dizaines de modules. Dans les grands projets, les chaînes réactives imprègnent toute l'architecture : de l'observation de UserDefaults via RxProperty aux requêtes réseau via Moya (un wrapper RxSwift sur Alamofire). Chaque module est isolé et communique via des interfaces réactives, ce qui simplifie le remplacement d'implémentation sans modifier les abonnés. Avec une architecture appropriée, RxSwift réduit la quantité de code par rapport aux approches classiques, car il n'est pas nécessaire d'écrire du code boilerplate pour KVO, Target-Action ou NotificationCenter.
RxSwift est activement utilisé dans les projets avec RxDataSources — une bibliothèque pour le travail réactif avec UITableView et UICollectionView. RxDataSources calcule automatiquement la différence entre les anciens et nouveaux ensembles de cellules et applique des changements animés. Cela libère le développeur du travail manuel avec beginUpdates/endUpdates et élimine les crashes dus à l'incohérence des données.
Pour le débogage des chaînes RxSwift, il existe l'opérateur debug() — il enregistre tous les événements : subscribe, next, error, completed, dispose. C'est un outil indispensable lors du développement de pipelines réactifs complexes. debug(String) prend un identifiant qui apparaît dans les logs. Pour le profilage mémoire, RxSwift.Resources.total affiche le nombre total d'Observables et Disposables actifs dans l'application — aide à identifier les fuites lorsque DisposeBag n'est pas nettoyé ou qu'un retain cycle maintient un abonnement. L'opérateur supplémentaire takeUntil(self.rx.deallocated) annule automatiquement l'abonnement lors de la désallocation de l'objet — c'est une couche supplémentaire de protection contre les fuites.
Lors de l'écriture de code RxSwift, il est important de suivre le principe d'Observable unique par abonnement : chaque ViewController ne doit pas créer plus d'un abonnement au même Observable — cela réduit le risque de conditions de concurrence. Pour la mémoïsation des Observables, on utilise l'opérateur share(), qui transforme un Observable froid en chaud avec un buffer replay de taille 1. Lors du travail avec des ressources partagées, utilisez connect() pour contrôler le début de l'émission — cela garantit que tous les abonnés se connectent avant le premier événement.
Le test du code RxSwift se fait via TestScheduler — un Scheduler virtuel qui permet de gérer le temps. testScheduler.createHotObservable(values) crée un Observable avec une séquence prédéfinie d'événements par temps virtuel. testScheduler.start() démarre le traitement. TestScheduler permet de vérifier dans quel ordre et à quel timestamp virtuel les événements se produisent, sans délais réels, rendant les tests rapides et déterministes.
Foire aux questions
Observable est une source froide : il n'émet pas d'événements avant l'abonnement. Subject est chaud : il émet des événements indépendamment des abonnés et permet l'insertion manuelle de valeurs via onNext. PublishSubject transmet uniquement les nouveaux événements, BehaviorSubject — le dernier plus les nouveaux.
DisposeBag stocke tous les abonnements Disposable. Lorsque DisposeBag est désalloué (par exemple, à la fermeture d'un ViewController), tous les abonnements stockés sont automatiquement annulés. Cela garantit qu'Observable n'enverra pas d'événement à un objet UI détruit.
Si la version iOS minimale est 13+ et que l'équipe connaît SwiftUI — choisissez Combine. Si le projet supporte iOS 12 et inférieur ou nécessite un plus grand ensemble d'opérateurs — RxSwift. Combine offre une meilleure intégration avec Foundation (URLSession, Timer, NotificationCenter).
Schedulers abstractisent les threads d'exécution. subscribeOn spécifie sur quel Scheduler l'abonnement est effectué (généralement en arrière-plan). observeOn détermine sur quel Scheduler les événements sont reçus (le plus souvent MainScheduler pour les mises à jour UI). SerialDispatchQueueScheduler fonctionne via GCD.
Oui, RxSwift peut être intégré avec SwiftUI via ObservableObject. Utilisez BehaviorRelay comme propriétés @Published : l'abonnement au Relay transmet les modifications à Combine, et SwiftUI redessine la View via @ObservedObject. C'est un pattern populaire de migration de UIKit vers SwiftUI.
Résumé
Nous développerons une application mobile clé en main
IT Sectr crée des applications iOS et Android pour les startups et les entreprises depuis 2017. Nous vous conseillerons et vous proposerons la meilleure solution.
Lisez aussi