I have tried to add an alert to the login button informing the user if they have entered an incorrect password. I added a showAlert.toggle to the signIn function but my syntax is wrong and XCode produces the following two errors:
"Value of tuple type '()' has no member 'alert'"
"Expected ',' separator"
Here is my ViewModel code:
func badPassword() -> Alert {
return Alert(title: Text("Incorrect password"))
}
func signIn(email: String, password: String) {
Auth.auth().signIn(withEmail: email, password: password) { (authResult, error) in
switch error {
case .some(let error as NSError) where error.code == AuthErrorCode.wrongPassword.rawValue:
showAlert.toggle()
.alert(isPresented: $showAlert, content: {
badPassword()}
print("wrong password")
case .some(let error):
print("Login error: \(error.localizedDescription)")
case .none:
if let user = authResult?.user {
print(user.uid)
DispatchQueue.main.async {
self.signedIn = true
}
}
}
}
}
}
Here is my View code:
struct SignInView: View {
@State var email = ""
@State var password = ""
@State var wrongPassword = false
@State var showAlert: Bool = false
@EnvironmentObject var viewModel: AppViewModel
var body: some View {
ZStack {
VStack {
Spacer()
HStack {
Image(systemName: "mail")
.foregroundColor(.gray)
TextField("Email Address", text: $email)
.disableAutocorrection(true)
.autocapitalization(.none)
.padding()
}
.frame(width: 325, height: 50)
.background(Color.black.opacity(0.05))
.cornerRadius(10)
HStack {
Image(systemName: "lock")
.foregroundColor(.gray)
SecureField("Password", text: $password)
.disableAutocorrection(true)
.autocapitalization(.none)
.padding()
}
.frame(width: 325, height: 50)
.background(Color.black.opacity(0.05))
.cornerRadius(10)
Button(action: {
guard !email.isEmpty, !password.isEmpty else {
return
}
viewModel.signIn(email: email, password: password)
}, label: {
Text("Sign In")
.frame(width: 200, height: 50)
.background(Color.blue)
.cornerRadius(8)
.foregroundColor(Color.white)
CodePudding user response:
You can use Alert like this in SwiftUI:
struct ContentView: View {
@StateObject var vm = ViewModel()
var body: some View {
ZStack {
}.alert(isPresented: $vm.showError, content: {
Alert(title: Text(vm.errorMessage))
})
}
}
And your ViewModel class:
class ViewModel: ObservableObject {
@Published var showError = false
var errorMessage = ""
func showError(message: String) {
errorMessage = message
showError = true
}
}
You can use showError(message: String) anywhere to show error. In your case:
switch error {
case .some(let error as NSError) where error.code == AuthErrorCode.wrongPassword.rawValue:
showError(message: "Wrong Password")
...
}