SwiftUI ObservedObject не обновляет представление после успешного входа в систему
Чтобы показать мой контент из моего корневого представления после успешного входа в систему, я попытался с 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
. Что мне не хватает?
РЕДАКТИРОВАТЬ
Вот новый аспект. У меня есть модель просмотра дляLoginView
для управления данными в полях даты. Когда нажимается кнопка входа в систему, я вызываюlogin()
в этой модели представления.
Мне нужно два .sink
обратные вызовы в модели представления, потому что я должен отклонить индикатор загрузки, установив loading
значение false.
Поэтому я не могу позвонить self.isLoggedIn = true
прямо потому, что я нахожусь в модели представления, а не LoginManager
. Вместо этого я звоню
self.loginManager.isLoggedIn = true
и я подозреваю, что эта линия не работает.
Связь между моделью представления и менеджером входа выполняется следующим образом
@ObservedObject var loginManager = LoginManager.shared
Однако после переноса этого на LoginManager
, Я действительно звоню self.isLoggedIn
оттуда. Это все еще не работает.
У меня два тезиса:
Возможно, представление неправильно настроено с
Group
и т.д. Я тоже пробовал использовать@ViewBuilder
и т.д, без разницы.Возможно, есть два экземпляра
LoginManager
, илиRootView
каким-то образом получить повторную инициализацию с новым экземпляром, гдеisLoggedIn
ложно. Но я создавал такие синглтоны Swift целую вечность:static 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 ответ
Думаю, у меня ошибка.
Я предположил .sink(receiveCompletion:
всегда есть ошибка из-за шаблона, о котором я имел в виду. Но вызывается блок завершения несмотря ни на что.
К сожалению, если вы вставите параметр error in
этого никогда не будет nil
но содержать что-то вроде
Combine.Subscribers.Completion<module.CustomError>.finished
Так что, я думаю, вам не следует снова проверять наличие ошибок.