Models and ViewModels

SignInViewModel.swift

Overview

The SignInViewModel.swift in ShipThatApp is designed to manage and encapsulate the logic for user sign-in operations throughout the application. This ViewModel acts as an intermediary between the SignInView and the AuthManager, handling user inputs, validating form data, and performing authentication actions.

Key Responsibilities

The SignInViewModel is responsible for:

  • Validating user credentials (such as email and password).
  • Initiating the sign-in or registration process through the AuthManager.
  • Reporting errors and updating the UI based on authentication status.
  • Sending magic link requests for passwordless authentication.

Properties

  • errorText: A String wrapped in @Published to notify the view about form errors or sign-in related errors.
  • isUserAuthenticated: A Boolean to track the authentication status of the user.

Functions

Form Validation

  • isFormValid(email: String, password: String) -> Bool: Validates the user input for email and password fields. It uses extensions on String to check for correct email formats and password strength.

Authentication Actions

  • registerNewUserWithEmail(email: String, password: String) async throws -> AppUser: Calls AuthManager to register a new user with their provided email and password.
  • sendMagicLink(email: String) async throws: Requests AuthManager to send a magic link to the given email address.
  • signInWithEmail(email: String, password: String) async throws -> AppUser: Invokes a method on AuthManager to sign in the user using their email and password.

Error Handling

  • Any error encountered during the aforementioned processes updates the errorText property. This includes scenarios such as an invalid email format, weak password, or failed sign-in attempts due to incorrect credentials or network issues.

Example Usage (Conceptual)

Here is a conceptual example of how SignInViewModel might be used in a view (actual source code is not provided):

struct SignInView: View {
    @StateObject private var signInViewModel = SignInViewModel()

    // ...

    var body: some View {
        Form {
            TextField("Email", text: $email)
            SecureField("Password", text: $password)

            if let errorText = signInViewModel.errorText {
                Text(errorText).foregroundColor(.red)
            }

            Button("Sign In") {
                Task {
                    do {
                        let user = try await signInViewModel.signInWithEmail(email: email, password: password)
                        // Handle successful sign-in
                    } catch {
                        // Handle error
                    }
                }
            }
        }
    }
}

Customization

Developers using SignInViewModel can:

  • Customize error messages and localization to improve the user experience.
  • Extend the ViewModel to include additional authentication providers if needed.
  • Integrate two-factor authentication mechanisms.

Testing

When writing tests for SignInViewModel, consider mocking the AuthManager to test form validation and authentication behavior without actual network calls.

Previous
Feature