Fiche 06.02 — MVVM dans SwiftUI avec ViewModel
Objectif
Savoir créer une feature SwiftUI avec MVVM : une View, un ViewModel, un état d’écran, un appel async et une gestion loading/error.
1. Structure simple
Pour une feature Profile, on peut avoir :
La View affiche. Le ViewModel prépare l’état.
2. Model
Le modèle représente les données utiles à l’app.
3. État d’écran
Un enum évite d’avoir trop de booléens :
Avec un enum, l’écran est dans un état clair.
4. ViewModel
@MainActor garantit que les mises à jour de l’UI se font sur le bon thread.
private(set) permet à la vue de lire state, mais pas de le modifier directement.
5. View SwiftUI
La View ne sait pas comment charger le profil. Elle sait seulement afficher l’état.
6. ViewModel avec service injecté
Dans une vraie app, le ViewModel appelle un service.
ViewModel :
Cette version est plus testable.
7. @StateObject ou @ObservedObject ?
Dans la vue qui crée le ViewModel :
Dans une sous-vue qui reçoit un ViewModel déjà créé :
@StateObject conserve l’objet. @ObservedObject observe un objet créé ailleurs.
En UIKit (rappel)
En UIKit, MVVM existe déjà, mais le binding est manuel. Le ViewModel expose l’état (souvent un ObservableObject avec @Published, ou de simples closures onChange), et le UIViewController s’abonne pour redessiner l’UI lui-même dans une méthode render().
ViewModel + abonnement Combine :
Mentalité : en UIKit tu décris les étapes (« quand l’état change, exécute render() qui modifie chaque vue »). En SwiftUI tu décris le résultat : le body est une fonction de l’état, recalculée automatiquement.
👉 En SwiftUI : pas de sink ni de render() — @Published / @Observable redessine le body tout seul quand l’état change.
Résumé
- MVVM sépare affichage et logique d’écran.
- La View affiche l’état du ViewModel.
- Le ViewModel expose des propriétés
@Published. - Les appels async se font souvent dans le ViewModel.
- Un enum d’état rend l’écran plus clair.
- L’injection de service rend le ViewModel testable.