Skip to content

Instantly share code, notes, and snippets.

@StewartLynch
Created June 22, 2022 21:50

Revisions

  1. StewartLynch created this gist Jun 22, 2022.
    74 changes: 74 additions & 0 deletions For @kadanas
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,74 @@
    //
    // Created for ErrorAlert
    // by Stewart Lynch on 2022-06-22
    // Using Swift 5.0
    //
    // Follow me on Twitter: @StewartLynch
    // Subscribe on YouTube: https://youTube.com/StewartLynch
    //

    import SwiftUI

    struct ContentView: View {
    @StateObject private var viewModel = ViewModel()
    var body: some View {
    VStack {
    Text(viewModel.authenticationStatus)
    Button {
    try? viewModel.authenticate()
    } label: {
    Text("Login")
    }
    .buttonStyle(.borderedProminent)
    }
    .alert(item: $viewModel.alertString) { alertString in
    Alert(title: Text("Login Error"),
    message: Text(alertString.errorString))
    }
    }
    }

    struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
    ContentView()
    }
    }


    class ViewModel: ObservableObject {
    @Published var authenticationStatus = "Please Log in"
    @Published var alertString: AlertString?


    enum AuthenticationError: Error {
    case failed
    }

    struct AlertString: Identifiable {
    let errorString: String
    var id: String {
    errorString
    }
    }

    func authenticate() throws {
    // This simulates a login that will sometimes fail.
    // If it is successful, it just updates the athenticationStatus property with that string
    // If it fails, it sets authenticationStatus to Try again but also sets the alertString
    // Published property to a non-optional instance of the AlertString struct and
    // The errorString property can then be used in your view for your alert Message
    // The key to this is to use the .alert(item: ) constructor instead of the .alert(.isPresented: ) one
    // This one triggers every time an optional property is set (alertString?) and the alert will
    // then give you that instance of that property from which we can extract the errorString
    // And use it in the Alert.

    let random = Bool.random()
    if random {
    authenticationStatus = "Logged in Successfully"
    } else {
    authenticationStatus = "Try again"
    self.alertString = AlertString(errorString: "Login Failed")
    throw AuthenticationError.failed
    }
    }
    }