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@Publishedto 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 onStringto check for correct email formats and password strength.
Authentication Actions
registerNewUserWithEmail(email: String, password: String) async throws -> AppUser: CallsAuthManagerto register a new user with their provided email and password.sendMagicLink(email: String) async throws: RequestsAuthManagerto send a magic link to the given email address.signInWithEmail(email: String, password: String) async throws -> AppUser: Invokes a method onAuthManagerto sign in the user using their email and password.
Error Handling
- Any error encountered during the aforementioned processes updates the
errorTextproperty. 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.