В цьому прикладі, UserData — це об’єкт класу, який містить декілька властивостей, що можуть бути використані в декількох views. Клас позначено як ObservableObject, тому його можна використовувати із @StateObject та @ObservedObject.
В ContentView ми створюємо новий об’єкт UserData, використовуючи @StateObject для збереження стану між переходами для різних views. В цьому випадку ContentView відображає дані користувача, візуалізує їх та містить посилання на інший view (ProfileView), який можна використовувати для редагування даних користувача.
У ProfileView ми дістаємо доступ до того ж об’єкта UserData, використовуючи @ObservedObject для модифікації даних користувача. Коли користувач змінює дані, вони автоматично оновлюються у ContentView, оскільки використовується той самий об’єкт UserData.
Примітка: Використовуйте @ObservedObject, якщо вам потрібно спостерігати за змінами в об’єкті класу з одного view, й @StateObject, якщо вам потрібно зберегти стан об’єкта класу, який впливає на відображення декількох views.
Якщо ви використовуєте @ObservedObject замість @StateObject для об’єкта, необхідного в декількох views, кожен view матиме власний екземпляр об’єкта, що може призвести до проблем із синхронізацією даних між views. Тому в цьому випадку краще використовувати @StateObject.
@EnvironmentObject
@EnvironmentObject — це property wrapper для передачі об’єктів даних через ієрархію views SwiftUI. Вона дає змогу дістати доступ до об’єкта даних з будь-якого views в ієрархії SwiftUI, що належить до контейнера Environment (наприклад, Scene, View, App тощо).
Уявіть, що у нас є додаток для керування списком завдань. Ми можемо мати корінь ContentView, який містить список завдань та можливість створювати нові завдання. Для цього ми створюємо окремий TaskListView, який відображає список завдань та кнопку для додавання нових завдань. Після додавання нового завдання користувач мусить бути перенаправлений на екран додавання завдання, тому ми створюємо окреме view AddTaskView.
Щоб передати об’єкт UserManager усім трьом views, ми можемо створити його екземпляр у ContentView, а потім передати його, як параметр до TaskListView та AddTaskView. Однак це може стати проблемою, якщо ми вирішимо додати ще більше вкладених view, оскільки нам доведеться передавати UserManager через багато проміжних views.
Натомість, ми можемо використовувати @EnvironmentObject для передачі UserManager вниз по ієрархії views. Отже, всі views, яким потрібен доступ до UserManager, можуть просто оголосити його як @EnvironmentObject та використовувати його за потребою.