SwiftUI结合Firebase鉴权:运行时切换根视图及启动页适配
嘿,刚好我在SwiftUI里折腾过类似的Firebase Auth流程,给你分享几个贴合SwiftUI状态驱动理念的优雅方案,比Storyboard那套逻辑更顺畅~
最推荐:状态驱动的根视图切换
SwiftUI的核心就是状态决定UI,我们可以把Auth状态抽成一个可观察的ViewModel,然后直接根据状态切换根视图,完全不需要手动写跳转逻辑。
步骤1:创建Auth状态管理ViewModel
这个ViewModel负责监听Firebase的Auth状态变化,把登录状态暴露给UI层:
import FirebaseAuth import Combine import Foundation class AuthViewModel: ObservableObject { @Published var currentUser: User? private var cancellables = Set<AnyCancellable>() init() { // 监听Auth状态的实时变化(登录、登出、token过期刷新都会触发) Auth.auth().addStateDidChangeListener { [weak self] auth, user in DispatchQueue.main.async { self?.currentUser = user } } } // 可以在这里封装登录、登出的业务逻辑 func signOut() throws { try Auth.auth().signOut() } }
步骤2:在App入口绑定状态切换视图
直接在App的根场景里,根据currentUser的存在与否显示对应的页面:
@main struct YourAwesomeApp: App { // 用@StateObject保证ViewModel在App生命周期内唯一 @StateObject private var authVM = AuthViewModel() var body: some Scene { WindowGroup { if let user = authVM.currentUser { DashboardView(user: user) .environmentObject(authVM) } else { AuthContainerView() // 包含登录/注册的鉴权页面 .environmentObject(authVM) } } } }
这个方案的优势:
- 完全贴合SwiftUI的设计理念,状态变UI自动变,不需要手动写跳转代码
- 实时监听Auth状态,比如用户在其他设备登出、token过期,UI会自动切换到鉴权页
- 逻辑解耦,Auth相关代码都在ViewModel里,页面只负责展示
进阶:带导航过渡的方案(适合多步鉴权)
如果你的鉴权流程需要多步跳转(比如登录→验证邮箱→仪表盘),可以用NavigationStack的路径绑定来实现更流畅的过渡:
1. 扩展ViewModel的导航状态
class AuthViewModel: ObservableObject { @Published var currentUser: User? @Published var navPath = NavigationPath() // 定义导航目标枚举 enum AuthDestination: Hashable { case signIn case signUp case emailVerification } init() { Auth.auth().addStateDidChangeListener { [weak self] auth, user in DispatchQueue.main.async { self?.currentUser = user // 根据状态自动调整导航路径 if user != nil { self?.navPath.removeLast(self?.navPath.count ?? 0) } else { self?.navPath.append(AuthDestination.signIn) } } } } }
2. 根视图绑定导航路径
struct RootView: View { @EnvironmentObject var authVM: AuthViewModel var body: some View { NavigationStack(path: $authVM.navPath) { if let user = authVM.currentUser { DashboardView(user: user) } else { // 占位视图,自动跳转到鉴权页 Color.clear .navigationDestination(for: AuthDestination.self) { dest in switch dest { case .signIn: SignInView() case .signUp: SignUpView() case .emailVerification: EmailVerificationView() } } } } } }
关键注意点
- 一定要用
addStateDidChangeListener,而不是只在初始化时检查Auth.auth().currentUser——前者能捕获所有Auth状态的实时变化,后者只能拿到启动时的状态 - 用
@StateObject初始化ViewModel,确保它在整个App生命周期内只实例化一次 - 登录成功后不需要手动写跳转,Firebase的监听器会自动更新
currentUser,UI会自动切换到仪表盘
内容的提问来源于stack exchange,提问作者Liam
相关产品推荐
相关产品推荐

