Передача привязок к дочерним моделям представления и их обновление

#swift #swiftui

#swift #swiftui

Вопрос:

В swiftui в моем основном представлении у меня есть объект среды для моего состояния приложения ( AppState класса), который включает запись пользователя. Идея в том, что есть только один пользователь, и все представления должны использовать этот один экземпляр класса user. So AppState создается @main и передается как an environmentObject для всех представлений. My AppState.user @Published — это экземпляр CurrentUser класса var.

Некоторым (большинству) вложенным представлениям не нужен полный AppState экземпляр, им просто нужны некоторые данные из него, например AppState.user экземпляр. И они должны иметь возможность обновлять экземпляр пользователя. Но вот тут-то мне и приходит запах, и мне интересно, не упускаю ли я чего-то.

В моем приложении есть серия экранов — раздел под названием «адаптация». Весь этот раздел должен знать о свойствах пользователя и обновлять их — вводила ли она X, завершила или пропустила адаптацию. Итак, мне нужно передать AppState.user встроенную модель представления:

 OnboardingSection()
  .environmentObject(OnboardingSectionVM(user: $appState.user))
 

…где OnboardingSectionVM.user находится var user: Binding<User> . Отлично работает для чтения текущего пользователя. Но теперь я хочу обновить пользователя на глобальном AppState уровне, и для этого я пишу эту функцию сохранения, и она кажется грязной:

 class OnboardingSectionVM: ObservableObject {
  var user: Binding<User>
  @Published var birthday: Date?

  init(currentUser: Binding<CurrentUser>) { ... }

  func save() {
    currentUser.wrappedValue.birthday = self.birthday
  }
}
 

Это правильно? При обновлении связанной переменной, подобной этой, обновляю ли я wrappedValue и будет ли это уведомлять все другие прослушиваемые представления AppState.user о том, что она изменилась? Это кажется грязным, как будто я работаю над привязкой, чтобы обновить базовое значение.

Комментарии:

1. Вы должны использовать только Binding для свойств представления. Для модели представления вы можете просто передать пользователя по ссылке, и если User это ObservableObject со @Published свойствами, устанавливающими birthday на объекте user, это вызовет соответствующее обновление для пользовательского интерфейса.

2. Я пробовал это, но раздел загрузки загружается на основе комбинации состояния приложения и пользовательских свойств. Я могу показывать экран входа в систему, или tabview, или что-то еще на основе состояния приложения и значений пользовательских свойств. Поэтому мне нужно, чтобы пользователь был @Published var в состоянии приложения и, следовательно, передавался по ссылкам в качестве привязки.

3. Вы нашли решение для этого?