Fiche 02.04 — @StateObject en SwiftUI
Objectif
Comprendre à quoi sert @StateObject, pourquoi il est utilisé avec un ViewModel, et comment il permet à une vue SwiftUI de garder un objet observable en mémoire.
1. L’idée à comprendre
@StateObject sert à créer et conserver un objet observable dans une vue SwiftUI.
Il est souvent utilisé pour créer un ViewModel.
Exemple :
À retenir :
2. Pourquoi on en a besoin
Une View SwiftUI est une struct.
Elle peut être recréée souvent par SwiftUI.
Si tu créais ton ViewModel comme une simple propriété, tu risquerais de le recréer trop souvent.
Pas adapté :
Correct :
@StateObject dit à SwiftUI :
3. Code minimal avec ViewModel
Ici :
CounterViewModelcontient la logique ;countest publié avec@Published;CounterViewobserve le ViewModel avec@StateObject;- quand
countchange, SwiftUI met à jour la vue.
4. ObservableObject
Pour être utilisé avec @StateObject, ton objet doit généralement respecter ObservableObject.
ObservableObject signifie :
Les valeurs qui doivent déclencher une mise à jour sont souvent marquées avec @Published.
5. @Published
@Published indique qu’une propriété du ViewModel peut déclencher une mise à jour de la vue.
Si username, isLoading ou errorMessage changent, la vue qui observe ce ViewModel peut être mise à jour.
6. Exemple réaliste : écran de profil
Vue :
Ici :
- la vue affiche le bon état selon le ViewModel ;
- le ViewModel gère le chargement ;
- la vue reste principalement responsable de l’interface.
7. Pourquoi @MainActor ?
Un ViewModel SwiftUI met souvent à jour l’interface.
Les changements d’interface doivent se faire sur le thread principal.
C’est pour ça qu’on écrit souvent :
@MainActor indique que les propriétés et fonctions de ce ViewModel doivent être utilisées sur le thread principal.
C’est particulièrement utile quand le ViewModel fait des appels async/await.
8. @StateObject vs @State
@State sert plutôt pour des valeurs simples locales.
@StateObject sert pour un objet observable, souvent un ViewModel.
Résumé :
9. @StateObject vs @ObservedObject
La différence est très importante.
@StateObject est utilisé quand la vue crée et possède l’objet.
@ObservedObject est utilisé quand l’objet est créé ailleurs et simplement reçu par la vue.
Résumé :
10. Exemple parent avec @StateObject, enfant avec @ObservedObject
Ici :
ProfileViewpossède le ViewModel ;ProfileHeaderViewl’observe seulement ;- il ne faut pas recréer un nouveau ViewModel dans la sous-vue.
11. Initialiser un @StateObject avec des paramètres
Si ton ViewModel a besoin de paramètres, tu peux l’initialiser dans le init de la vue.
Vue :
Le _viewModel permet d’initialiser le wrapper @StateObject.
C’est une syntaxe normale quand tu dois construire un StateObject avec un paramètre.
12. Injection de dépendance simple
Dans une app plus propre, ton ViewModel peut recevoir un service.
Vue :
Cette approche permet plus tard de remplacer MockProfileService par :
- un vrai service API ;
- un service Firebase ;
- un mock pour les tests ;
- un fake pour les previews.
13. Preview avec @StateObject
Si la vue crée son propre ViewModel avec @StateObject, tu peux la prévisualiser directement.
Si tu veux injecter un service de preview :
L’intérêt est de ne pas dépendre d’une vraie API ou de Firebase dans la preview.
14. Points à connaître
Ne crée pas un ViewModel avec @ObservedObject si la vue doit le posséder
Pas idéal :
Préférable :
Si la vue crée l’objet, utilise @StateObject.
Évite de mettre la logique métier dans la vue
Pas idéal :
Préférable :
La vue affiche.
Le ViewModel prépare les données d’affichage.
@StateObject garde l’objet tant que la vue reste au même endroit
SwiftUI peut relire le body, mais le ViewModel n’est pas recréé à chaque fois.
C’est l’un des intérêts principaux de @StateObject.
15. Note sur @Observable
Dans les versions récentes de SwiftUI, Apple propose aussi le système d’observation avec @Observable.
Mais ObservableObject, @Published, @StateObject et @ObservedObject restent très importants à comprendre, car ils sont encore très présents dans beaucoup de projets iOS existants.
Dans ce cours, on apprend d’abord cette approche classique, puis on pourra voir @Observable plus tard.
Résumé
À retenir :
@StateObjectsert à créer et conserver un objet observable dans une vue ;- il est souvent utilisé pour un ViewModel ;
- l’objet doit généralement respecter
ObservableObject; - les propriétés qui déclenchent l’UI sont souvent marquées avec
@Published; - si la vue crée le ViewModel, utilise
@StateObject; - si la vue reçoit le ViewModel, utilise plutôt
@ObservedObject; - un ViewModel SwiftUI est souvent marqué
@MainActor; @StateObjectest une base importante pour MVVM en SwiftUI.