Fiche 02.06 — @EnvironmentObject en SwiftUI
Objectif
Comprendre à quoi sert @EnvironmentObject, comment il permet de partager un objet observable dans plusieurs vues, et quand l’utiliser à la place de @StateObject, @ObservedObject ou @Binding.
1. L’idée à comprendre
@EnvironmentObject permet de partager un objet observable dans une partie de l’application sans devoir le passer manuellement de vue en vue.
Sans @EnvironmentObject, tu pourrais devoir faire ça :
Avec @EnvironmentObject, tu injectes l’objet une fois au-dessus dans la hiérarchie :
Puis les vues qui en ont besoin le récupèrent directement :
À retenir :
2. Code minimal
Injection dans la racine :
Utilisation dans une vue :
3. Exemple avec une racine d’app
@EnvironmentObject est souvent utilisé pour une session utilisateur.
LoginView peut modifier la session :
ProfileView peut aussi y accéder :
Ici, LoginView, ProfileView et AppRootView utilisent le même SessionManager.
4. Exemple avec une TabView
Même si MainTabView ne transmet pas directement session, ProfileView peut quand même y accéder avec :
Parce que session a été injecté plus haut dans :
5. Quand utiliser @EnvironmentObject
Utilise @EnvironmentObject pour des objets partagés par plusieurs vues éloignées.
Exemples fréquents :
Cas typiques :
- session utilisateur ;
- état de connexion ;
- profil utilisateur courant ;
- panier dans une app e-commerce ;
- thème global ;
- navigation globale ;
- réglages globaux de l’app.
6. Quand ne pas utiliser @EnvironmentObject
N’utilise pas @EnvironmentObject pour tout.
Si la donnée appartient à une seule vue :
Si la donnée est seulement transmise à une sous-vue proche :
Si une sous-vue reçoit un ViewModel précis :
@EnvironmentObject est surtout utile quand passer l’objet manuellement deviendrait lourd ou répétitif.
7. @EnvironmentObject vs @StateObject
@StateObject crée et possède l’objet.
@EnvironmentObject récupère un objet injecté plus haut.
Résumé :
Dans une app, tu peux utiliser les deux ensemble :
Puis dans les vues :
8. @EnvironmentObject vs @ObservedObject
@ObservedObject est transmis explicitement :
@EnvironmentObject est récupéré automatiquement depuis l’environnement :
Résumé :
9. Preview avec @EnvironmentObject
Si une vue utilise @EnvironmentObject, la preview doit fournir l’objet.
Si tu oublies .environmentObject(...), la preview peut planter au lancement.
Exemple complet :
Si cette syntaxe pose problème dans Xcode, crée une vue wrapper :
10. Exemple avec un thème global
@EnvironmentObject peut aussi servir pour un thème d’app.
Injection :
Utilisation :
11. Exemple avec un panier
Vue produit :
Vue tabbar :
Ici, plusieurs vues utilisent le même CartManager.
12. Points à connaître
L’objet doit être injecté plus haut
Si une vue déclare :
Alors une vue au-dessus doit faire :
Sinon l’app peut planter au runtime.
@EnvironmentObject crée une dépendance implicite
Avec @ObservedObject, tu vois la dépendance dans l’init :
Avec @EnvironmentObject, la dépendance est moins visible :
mais la vue a quand même besoin de :
Donc utilise @EnvironmentObject pour les vrais objets globaux, pas pour tout.
Évite les EnvironmentObjects trop énormes
Un seul objet global qui contient tout peut devenir difficile à maintenir.
Pas idéal :
Préférable : plusieurs objets spécialisés si nécessaire.
Exemple :
Résumé
À retenir :
@EnvironmentObjectpermet de récupérer un objet partagé injecté plus haut ;- il évite de passer le même objet manuellement à beaucoup de vues ;
- l’objet doit respecter
ObservableObject; - ses propriétés importantes sont souvent en
@Published; - on crée souvent l’objet avec
@StateObjectdans la racine ; - on l’injecte avec
.environmentObject(...); - on le lit avec
@EnvironmentObjectdans les vues enfants ; - si tu oublies l’injection, l’app ou la preview peut planter ;
- utilise-le pour des objets réellement partagés comme session, thème, panier ou router.