Чтобы отобразить содержимое из моего root представления после успешного входа в систему, я попытался использовать ObservedObject
и EnvironmentObject
, но безрезультатно.
Например, следующим образом:
struct RootView: View {
@EnvironmentObject var loginManager: LoginManager
var body: some View {
Group {
if loginManager.isLoggedIn {
SegmentedView()
}
else {
WelcomeView()
}
}
}
}
class LoginManager: ObservableObject {
static let shared = LoginManager()
var cancellable = Set<AnyCancellable>()
@Published var isLoggedIn = false
...
func login(...) {
...
// on success
self.isLoggedIn = true
}
LoginManager
сохраняется в SceneDelegate
и помещается в среду:
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
var loginManager = LoginManager.shared
...
// the view passed to window.rootUiewController via UIHostingController
let contentView = RootView().environmentObject(loginManager)
После входа в систему он возвращается обратно в мой WelcomeView
. Что мне не хватает?
EDIT
Вот новый аспект. У меня есть модель представления для LoginView
для управления данными в полях даты. Когда кнопка входа в систему нажата, я вызываю метод login()
в этой модели представления.
Мне нужно два .sink
обратных вызова в модели представления, потому что я должен отклонить индикатор загрузки, установив loading
flag на false.
Поэтому я не могу вызвать self.isLoggedIn = true
напрямую, потому что я использую модель представления, а не LoginManager
. Вместо этого я звоню
self.loginManager.isLoggedIn = true
и подозреваю, что эта строка не работает.
Связь между моделью представления и менеджером входа выполняется следующим образом
@ObservedObject var loginManager = LoginManager.shared
Однако , после переключения на LoginManager
я действительно звоню на self.isLoggedIn
оттуда. Он по-прежнему не работает.
У меня есть два тезиса:
Возможно, представление неправильно настроено с помощью Group
et c. Я также пробовал использовать @ViewBuilder
et c, без разницы.
Может быть, есть два экземпляра LoginManager
, или RootView
каким-то образом переинициализирован с новым экземпляром, где isLoggedIn
ложно. Но я создавал такие синглтоны Swift целую вечность:
stati c let shared = LoginManager ()
и никогда не испытывал никаких проблем.
Как упоминалось в комментариях, есть еще одна ошибка, с которой я столкнулся при переключении всех на @EnvironmentObject
:
Fatal error: No ObservableObject of type LoginManager found. A View.environmentObject(_:) for LoginManager may be missing as an ancestor of this view.: file SwiftUI, line 0