У меня есть класс Router с одним перечислением Routes для всех моих маршрутов. .
Код: Выделить всё
final class Router: ObservableObject {
public enum Routes: Hashable {
case landing
case emailAuth
case home
}
@Published var path: [Routes] = []
func navigate(to destination: Routes) {
path.append(destination)
}
func navigateBack() {
path.removeLast()
}
func navigateToRoot() {
path.removeLast(path.count)
}
}
Код: Выделить всё
enum AuthState {
case unAuthenticated
case authenticated
}
@MainActor
class AuthViewModel: ObservableObject {
@AppStorage("email") var emailStore: String?
@Published var email = ""
@Published var errorMessage = ""
@Published var authState: AuthState = .unAuthenticated
@Published var user: User?
@Published var userEmail = ""
init() {
registerAuthStateHandler()
}
private var authStateHandle: AuthStateDidChangeListenerHandle?
func registerAuthStateHandler() {
if authStateHandle == nil {
authStateHandle = Auth.auth().addStateDidChangeListener{auth, user in
self.user = user
self.userEmail = user?.email ?? "(unknown)"
if (user != nil) {
self.authState = .authenticated
} else {
self.authState = .unAuthenticated
}
print("Curr authState: \(self.authState)")
}
}
}
}
...
Код: Выделить всё
struct ContentView: View {
@StateObject var authViewModel: AuthViewModel = AuthViewModel()
@StateObject var router: Router = Router()
var body: some View {
NavigationStack(path: $router.path) {
// Text("Loading...")
LandingScreen(path: $router.path)
.navigationDestination(for: Router.Routes.self) { route in
switch route {
case .landing:
let _ = print("landing")
LandingScreen(path: $router.path)
case .emailAuth:
AuthEmail(path: $router.path)
case .home:
Text("TODO: home page")
}
}
}
.onAppear {
print("Curr authState: \(authViewModel.authState)")
if (authViewModel.authState == .authenticated) {
router.path = [.home]
} else {
router.path = [.landing]
}
print(router.path)
}
.environmentObject(router)
.environmentObject(authViewModel)
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
.environmentObject(AuthViewModel())
.environmentObject(Router())
}
}
Код: Выделить всё
struct LandingScreen: View {
@EnvironmentObject var authViewModel: AuthViewModel
@Binding var path: [Router.Routes]
var body: some View {
// ...
NavigationStack {
NavigationLink(value: Router.Routes.emailAuth) {
Text("Continue with email")
}
}
}
Код: Выделить всё
Curr authState: unAuthenticated
[app.Router.Routes.landing]
landing
Подробнее здесь: https://stackoverflow.com/questions/784 ... -correct-s