You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 10:52:41