ios - 登录后SwiftUI LoginView不会消失

标签 ios authentication swiftui environment observableobject

我正在使用 AppStateView()检查用户是否登录:

struct AppStateView: View {

    @EnvironmentObject var appState: AppState

    var body: some View {
        if (self.appState.user != nil) {
            return AnyView(ContentView().environmentObject(appState))
        } else {
            return AnyView(LoginView().environmentObject(appState))
        }
    }
}

里面LoginView() :
struct LoginView: View {

    @EnvironmentObject var appState: AppState

    @State private var username: String = ""
    @State private var password: String = ""

    var body: some View {
        NavigationView {
            VStack {
                TextField("Username", text: $username)
                SecureField("Password", text: $password)
                Button(action: {
                    self.appState.login(username: self.username, password: self.password) { user in
                        if user.accountId != 0 {
                            print("logged in")
                        } else {
                            print("not logged in")
                        }
                    }

                }) {
                    Text("LOGIN")
                }
                NavigationLink(destination: RegisterView()) {
                    Text("Sign Up")
                }
            }
        }
    }
}

有一个按钮调用 appState.login 函数:
struct User: Codable {
    let uid: Int
    let name: String
    let accountname: String
    let accountId: Int
    let startBalance: Double
}

class AppState: ObservableObject {

    @Published var user: User? = nil

    let apiURL: String = "http://localhost/api.php?"

    init() {
        if let user = UserDefaults.standard.object(forKey: "user") as? Data {
            if let loadedUser = try? JSONDecoder().decode(User.self, from: user) {
                self.user = loadedUser
            }
        }
    }

    func login(username: String, password: String, completion: @escaping (User) -> ()) {

        let urlstring = "\(apiURL)get_users&username=\(username)&password=\(password)"

        guard let url = URL(string: urlstring) else { return }

        URLSession.shared.dataTask(with: url) { (data, _, error) in

            guard let data = data, error == nil else {
                debugPrint("Fehler beim Laden von \(url)", String(describing: error))
                return
            }

            let user = try! JSONDecoder().decode(User.self, from: data)
            if let encoded = try? JSONEncoder().encode(user) {
                UserDefaults.standard.set(encoded, forKey: "user")
            }

            DispatchQueue.main.async {
                completion(user)
            }
        }.resume()

    }

    func logout() {
        self.user = nil
        UserDefaults.standard.removeObject(forKey: "user")
    }

}

根据我对可观察对象的理解,我认为在按下登录按钮后,用户会得到更新,因此 LoginView() View 在用户登录时重新加载。但它必须切换到 AppStateView() .在 LoginView() 中添加第二个检查感觉有点奇怪显示LoginView()AppStateView()因为我已经在“父 View ”中做 AppStateView() .

最佳答案

下面是固定的部分代码

Button(action: {
    self.appState.login(username: self.username, password: self.password) { user in
        if user.accountId != 0 {
            print("logged in")
            self.appState.user = user       // << here !!
        } else {
            print("not logged in")
        }
    }

}) {
    Text("LOGIN")
}

关于ios - 登录后SwiftUI LoginView不会消失,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61971713/

相关文章:

iphone - 如何在 iOS 应用程序中动态链接设备框架?

java - 如何从java桌面应用程序中保存fos_user数据

swift - 正确设置 SwiftUI 中的 PopOverViewController

swift - 如何将接收器结果分配给变量

swift - 如何在 Swift 的 Structure 中声明一个特定的协议(protocol)?

ios - 从以前的 ios 应用程序版本检索数据

iOS 9 (Xcode 7) Facebook API/FBSDKCoreKit.framework/FBSDKCoreKit(FBSDKAccessToken.o)' 不包含位码

iphone - UIImage 具有光滑的 quartz 圆角

PHP 登录总是返回错误

node.js - 通过用户网格身份验证防止共享 session