SwiftUI ObservedObject не обновляет представление после успешного входа в систему - PullRequest
0 голосов
/ 05 августа 2020

Чтобы отобразить содержимое из моего 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 оттуда. Он по-прежнему не работает.

У меня есть два тезиса:

  1. Возможно, представление неправильно настроено с помощью Group et c. Я также пробовал использовать @ViewBuilder et c, без разницы.

  2. Может быть, есть два экземпляра 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

1 Ответ

0 голосов
/ 06 августа 2020

Кажется, я получил ошибку.

Я предполагал, что .sink(receiveCompletion: всегда содержит ошибку, потому что шаблон, на который я ссылался. Но блок завершения вызывается несмотря ни на что. вы не должны снова проверять наличие ошибок.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...