【问题标题】:SwiftUI MVVM how to show alert after a functionSwiftUI MVVM如何在函数后显示警报
【发布时间】:2021-04-30 22:29:59
【问题描述】:

我正在使用 MVVM 架构创建用户登录页面,如果文本字段为空或用户名/密码错误,我想显示一个警报页面。所以在登录点击和 API 调用之后,如果登录失败,我想显示一个警报,但是我尝试更改状态但仍然没有显示警报。

登录查看

struct LoginView: View {
    @ObservedObject var user: User
    @ObservedObject var viewModel = LoginViewModel()
    @State var inputUser: String = ""
    @State var inputPass: String = ""
    @State private var showingAlert = true
    
    var body: some View {
        ScrollView {
            VStack(alignment: .leading) {
                Group {
                    Text("Login")
                    CustomTextField(placeHolder: "Username", value: $viewModel.user)
                    CustomTextField(placeHolder: "Password", value: $viewModel.pass)
                    Button(action: {
                        self.viewModel.login { (isSuccess) in
                            if isSuccess {
                                self.user.tokenIsActive = true
                            } else {
                                // if login failed, show alert, but alert not showing
                                self.showingAlert = true
                            }
                        }
                    }) {
                        Text("Sign In")
                    }.buttonStyle(PrimaryButtonStyle())
                    .alert(isPresented: $showingAlert) {
                        Alert(title: Text("Error"), message: Text("Invalid username / password"), dismissButton: .default(Text("Got it!")))
                    }
                }
            }
        }
    }
}

登录视图模型

class LoginViewModel: ObservableObject, LoginService {
    var apiSession: APIService
    
    @Published var user = ""
    @Published var pass = ""
    
    @Published var accessToken: String?
    @Published var refreshToken: String?
    @Published var showingAlert = true
    
    var cancellables = Set<AnyCancellable>()
    
    init(apiSession: APIService = APISession()) {
        self.apiSession = apiSession
    }
    
    func login(_ completion: @escaping ((Bool)->Void)) {
        let cancellable = self.loginUser(user: user, pass: pass)
            .sink(receiveCompletion: { result in
                switch result {
                case .failure(let error):
                    print("Handle error: \(error)")
                case .finished:
                    break
                }
                
            }) { (result) in
                completion(true)
                self.accessToken = result.accessToken
                self.refreshToken = result.refreshToken
                UserDefaults.standard.set(self.accessToken, forKey: "AccessToken")
                UserDefaults.standard.set(self.refreshToken, forKey: "RefreshToken")
        }
        cancellables.insert(cancellable)
    }
}

如何显示警报?提前谢谢大家。

【问题讨论】:

    标签: swift xcode mvvm swiftui


    【解决方案1】:

    如果我正确理解了您的流程,则问题在于登录逻辑

    let cancellable = self.loginUser(user: user, pass: pass)
        .receive(on: DispatchQueue.main)        // << add also this one !!
        .sink(receiveCompletion: { result in
            switch result {
            case .failure(let error):
                print("Handle error: \(error)")
                completion(false)               // << here !!
            case .finished:
                break
            }
            
        }) { (result) in
            self.accessToken = result.accessToken
            self.refreshToken = result.refreshToken
            UserDefaults.standard.set(self.accessToken, forKey: "AccessToken")
            UserDefaults.standard.set(self.refreshToken, forKey: "RefreshToken")
            completion(true) // obviously should be called here !!
                             // and if result is provided always, ie. for 
                             // failed login as well, then conditional
                             // completion should be called.
    }
    

    【讨论】:

    • 非常感谢您的回答。我对 Swift 很陌生,你能举个例子说明“条件完成”是如何实现的吗?
    猜你喜欢
    • 1970-01-01
    • 2021-08-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多