带有 Publishers 的身份验证 SwiftUI 的编程导航
Programatic navigation on authentication SwiftUI with Publishers
我在 SwitUI 应用程序中有此验证代码。 SessionStore
是一个可观察对象,它被注入到应用程序的主入口点。当标志成功时,然后导航到仪表板。 isLogin
变量改变但重定向没有发生。我不明白哪里做错了。
// 主视图
struct MyApp: App {
@StateObject var session = SessionStore()
init() {
FirebaseApp.configure()
}
var body: some Scene {
WindowGroup {
SplashScreenView()
.environmentObject(session)
}
}
}
// 重定向到登录或仪表板的启动画面视图
struct SplashScreenView: View {
@StateObject var session = SessionStore()
var body: some View {
Group {
if session.isLogedIn {
DashboardScreen()
} else {
SignInScreen()
}
}
}
}
// 会话存储
class SessionStore: ObservableObject {
@Published var session: User?
@Published var profile: UserProfile?
@Published var isLogedIn = false
private var profileRepository = UserProfileRepository()
func signUp(email: String, password: String, firstName: String, lastName: String, city: String, completion: @escaping (_ profile: UserProfile?, _ error: Error?) -> Void) {
Auth.auth().createUser(withEmail: email, password: password) { (result, error) in
if let error = error {
print("Error signing up: \(error)")
completion(nil, error)
return
}
guard let user = result?.user else { return }
print("User (user.uid) signed up.")
let userProfile = UserProfile(uid: user.uid, firstName: firstName, lastName: lastName, city: city)
self.profileRepository.createProfile(profile: userProfile) { (profile, error) in
if let error = error {
print("Error while fetching the user profile: \(error)")
completion(nil, error)
return
}
self.profile = profile
completion(profile, nil)
}
}
}
func signIn(email: String, password: String, completion: @escaping (_ profile: UserProfile?, _ error: Error?) -> Void) {
Auth.auth().signIn(withEmail: email, password: password) { [self] (result, error) in
if let error = error {
print("Error signing in: \(error)")
completion(nil, error)
return
}
guard let user = result?.user else { return }
print("User \(user.uid) signed in.")
self.isLogedIn = true
self.profileRepository.fetchProfile(userId: user.uid) { (profile, error) in
if let error = error {
print("Error while fetching the user profile: \(error)")
completion(nil, error)
return
}
self.profile = profile
completion(profile, nil)
}
}
}
func signOut() {
do {
try Auth.auth().signOut()
self.session = nil
self.profile = nil
} catch let signOutError as NSError {
print("Error signing out: \(signOutError)")
}
}
}
// 在我看来,我调用该方法并更新登录状态或注册。改变状态但不重定向
struct SignInScreen: View {
@ObservedObject var sessionStore = SessionStore()
var body: some View {
Button(action:signIn, label: {
Text("Sign In")
})
}
func signIn() {
loading = true
error = false
sessionStore.signIn(email: signInViewModel.emailAddress, password: signInViewModel.password) { (profile, error) in
if let error = error {
print("Error when signing up: \(error)")
return
}
sessionStore.isLogedIn = true
}
}
}
您必须在 SplashScreenView 中使用 @EnvironmentObject var session: SessionStore 而不是 @StateObject。
目标是只有一个 SessionStore() 实例。
在这里,你重新定义了两次:@StateObject var session = SessionStore()
在您的 MyApp 中,执行
@StateObject var session = SessionStore()
在其他人看来,做
@EnvironmentObject var session: SessionStore
并且,您忘记将环境对象传递给 SignInScreen
.environmentObject(session)
我看到你在使用 firebase。如果您需要检查身份验证状态,这样做会很容易。
您的主要条目视图
struct MyApp: App {
@StateObject var session = SessionStore()
init() {
FirebaseApp.configure()
}
var body: some Scene {
WindowGroup {
SplashScreenView()
.environmentObject(session)
}
}
}
在您的会话存储中添加此代码以检查当前是否使用 FirebaseAuth
而不是手动登录。
class SessionStore: ObservableObject {
// Previous code
var isSignIn: Bool {
Auth.auth().currentUser?.uid != nil
}
}
在启动画面中检查 isSignIn
。
struct SplashScreenView: View {
@EnvironmentObject var session: SessionStore
var body: some View {
Group {
if session.isSignIn {
DashboardScreen()
} else {
SignInScreen()
}
}
}
}
我在 SwitUI 应用程序中有此验证代码。 SessionStore
是一个可观察对象,它被注入到应用程序的主入口点。当标志成功时,然后导航到仪表板。 isLogin
变量改变但重定向没有发生。我不明白哪里做错了。
// 主视图
struct MyApp: App {
@StateObject var session = SessionStore()
init() {
FirebaseApp.configure()
}
var body: some Scene {
WindowGroup {
SplashScreenView()
.environmentObject(session)
}
}
}
// 重定向到登录或仪表板的启动画面视图
struct SplashScreenView: View {
@StateObject var session = SessionStore()
var body: some View {
Group {
if session.isLogedIn {
DashboardScreen()
} else {
SignInScreen()
}
}
}
}
// 会话存储
class SessionStore: ObservableObject {
@Published var session: User?
@Published var profile: UserProfile?
@Published var isLogedIn = false
private var profileRepository = UserProfileRepository()
func signUp(email: String, password: String, firstName: String, lastName: String, city: String, completion: @escaping (_ profile: UserProfile?, _ error: Error?) -> Void) {
Auth.auth().createUser(withEmail: email, password: password) { (result, error) in
if let error = error {
print("Error signing up: \(error)")
completion(nil, error)
return
}
guard let user = result?.user else { return }
print("User (user.uid) signed up.")
let userProfile = UserProfile(uid: user.uid, firstName: firstName, lastName: lastName, city: city)
self.profileRepository.createProfile(profile: userProfile) { (profile, error) in
if let error = error {
print("Error while fetching the user profile: \(error)")
completion(nil, error)
return
}
self.profile = profile
completion(profile, nil)
}
}
}
func signIn(email: String, password: String, completion: @escaping (_ profile: UserProfile?, _ error: Error?) -> Void) {
Auth.auth().signIn(withEmail: email, password: password) { [self] (result, error) in
if let error = error {
print("Error signing in: \(error)")
completion(nil, error)
return
}
guard let user = result?.user else { return }
print("User \(user.uid) signed in.")
self.isLogedIn = true
self.profileRepository.fetchProfile(userId: user.uid) { (profile, error) in
if let error = error {
print("Error while fetching the user profile: \(error)")
completion(nil, error)
return
}
self.profile = profile
completion(profile, nil)
}
}
}
func signOut() {
do {
try Auth.auth().signOut()
self.session = nil
self.profile = nil
} catch let signOutError as NSError {
print("Error signing out: \(signOutError)")
}
}
}
// 在我看来,我调用该方法并更新登录状态或注册。改变状态但不重定向
struct SignInScreen: View {
@ObservedObject var sessionStore = SessionStore()
var body: some View {
Button(action:signIn, label: {
Text("Sign In")
})
}
func signIn() {
loading = true
error = false
sessionStore.signIn(email: signInViewModel.emailAddress, password: signInViewModel.password) { (profile, error) in
if let error = error {
print("Error when signing up: \(error)")
return
}
sessionStore.isLogedIn = true
}
}
}
您必须在 SplashScreenView 中使用 @EnvironmentObject var session: SessionStore 而不是 @StateObject。
目标是只有一个 SessionStore() 实例。 在这里,你重新定义了两次:@StateObject var session = SessionStore()
在您的 MyApp 中,执行
@StateObject var session = SessionStore()
在其他人看来,做
@EnvironmentObject var session: SessionStore
并且,您忘记将环境对象传递给 SignInScreen
.environmentObject(session)
我看到你在使用 firebase。如果您需要检查身份验证状态,这样做会很容易。
您的主要条目视图
struct MyApp: App {
@StateObject var session = SessionStore()
init() {
FirebaseApp.configure()
}
var body: some Scene {
WindowGroup {
SplashScreenView()
.environmentObject(session)
}
}
}
在您的会话存储中添加此代码以检查当前是否使用 FirebaseAuth
而不是手动登录。
class SessionStore: ObservableObject {
// Previous code
var isSignIn: Bool {
Auth.auth().currentUser?.uid != nil
}
}
在启动画面中检查 isSignIn
。
struct SplashScreenView: View {
@EnvironmentObject var session: SessionStore
var body: some View {
Group {
if session.isSignIn {
DashboardScreen()
} else {
SignInScreen()
}
}
}
}