Login and Sign Up
Learn how to implement login and sign up in your app

Login and Sign Up Module
The LoginAndSignUp module is a complete user authentication solution, providing login, registration, forgot password, and email verification functionality.
We will provide more beautiful login and registration pages in the future, so stay tuned.
Module Structure
LoginAndSignUp/
├── View/
│ └── LoginAndSignUp.swift # Main view, manages login/signup switching
└── SubPages/
├── SignIn/View/
│ └── SignInView.swift # Login interface
├── SignUp/View/
│ └── SignUpView.swift # Registration interface
├── ForgotPwd/View/
│ └── ForgotPwdView.swift # Forgot password
└── VerifyEmailView/View/
└── VerifyEmailView.swift # Email verificationCore Features
1. Main View Switching
The main view uses state management to switch between login and registration interfaces, providing smooth sliding animations:
struct LoginAndSignUp: View {
@State private var showSignUp = false
var body: some View {
if showSignUp {
SignUpView(showSignIn: $showSignUp)
.transition(.asymmetric(
insertion: .move(edge: .trailing),
removal: .move(edge: .trailing)
))
} else {
SignInView(showSignUp: $showSignUp)
.transition(.asymmetric(
insertion: .move(edge: .leading),
removal: .move(edge: .leading)
))
}
}
}2. Login Functionality
Supports two login methods:
- Email and password login
- Apple ID login
Key Features:
- Real-time input validation (email format, password strength)
- Forgot password link
- Loading state indicators
- Toast message notifications
func signInWithEmail() {
Task {
do {
try await authManager.signIn(email: account, password: password)
} catch {
print("signInWithEmailError:\(error)")
}
}
}
func signInWithApple(idToken: String) {
Task {
do {
try await authManager.signInWithApple(idToken: idToken)
} catch {
print("signInWithAppleError:\(error)")
}
}
}3. Registration Functionality
Registration Flow:
- User enters email and password
- Real-time input format validation
- Submit registration request
- Automatically redirect to login page on success
Input Validation Rules:
- Email format validation
- Password length (6-12 characters)
- Password must contain letters
func onSignUp() {
Task {
do {
try await authManager.signUp(email: account, password: password)
} catch {
print("onSignUpError:\(error)")
}
}
}4. Forgot Password
Provides password reset functionality, allowing users to:
- Enter email address
- Set new password
- Validate input validity
- Send reset request
5. Email Verification
When users need to verify their email after registration, displays verification interface:
- Prompts user to check email
- Provides resend verification email functionality
- Monitors application state changes
Button(action: {
isLoading = true
Task {
do {
try await authManager.resendVerificationEmail(email: email)
isLoading = false
} catch {
isLoading = false
}
}
}) {
Text("resend_verification_email")
.font(.title3)
}Authentication Management
The module handles all authentication logic through AuthManager:
- Supabase Integration: Uses Supabase as backend authentication service
- State Management: Automatically manages user login state
- Session Handling: Handles token refresh and expiration
- Subscription Integration: Supports RevenueCat and StoreKit2
User Interface Features
1. Smooth Transitions
- Sliding animations between login and registration
- Loading state indicators
- Visual feedback for user actions
2. Input Validation
- Real-time email format checking
- Password strength requirements
- Clear error messaging
3. Apple Sign-In Integration
- Native Apple ID authentication
- Seamless user experience
- Privacy-focused approach
4. Responsive Design
- Adapts to different screen sizes
- Keyboard-aware interface
- Accessibility support
Authentication Flow
1. Login Process
struct SignInView: View {
@EnvironmentObject private var authManager: AuthManager
@State private var account = ""
@State private var password = ""
@State private var isLoading = false
var body: some View {
VStack(spacing: 20) {
// Email input
TextField("Email", text: $account)
.textFieldStyle(RoundedBorderTextFieldStyle())
.keyboardType(.emailAddress)
.autocapitalization(.none)
// Password input
SecureField("Password", text: $password)
.textFieldStyle(RoundedBorderTextFieldStyle())
// Sign in button
Button("Sign In") {
signInWithEmail()
}
.disabled(account.isEmpty || password.isEmpty || isLoading)
// Apple Sign In
SignInWithAppleButton { request in
request.requestedScopes = [.fullName, .email]
} onCompletion: { result in
handleAppleSignIn(result)
}
}
}
}2. Registration Process
struct SignUpView: View {
@EnvironmentObject private var authManager: AuthManager
@State private var account = ""
@State private var password = ""
@State private var isLoading = false
var body: some View {
VStack(spacing: 20) {
// Email input with validation
TextField("Email", text: $account)
.textFieldStyle(RoundedBorderTextFieldStyle())
.keyboardType(.emailAddress)
.autocapitalization(.none)
.overlay(
RoundedRectangle(cornerRadius: 8)
.stroke(isValidEmail ? Color.green : Color.red, lineWidth: 1)
)
// Password input with strength indicator
SecureField("Password", text: $password)
.textFieldStyle(RoundedBorderTextFieldStyle())
PasswordStrengthIndicator(password: password)
// Sign up button
Button("Sign Up") {
onSignUp()
}
.disabled(!isValidInput || isLoading)
}
}
private var isValidEmail: Bool {
account.contains("@") && account.contains(".")
}
private var isValidInput: Bool {
isValidEmail && password.count >= 6 && password.count <= 12
}
}Error Handling
1. Authentication Errors
enum AuthError: LocalizedError {
case invalidCredentials
case emailNotVerified
case networkError
case unknownError(String)
var errorDescription: String? {
switch self {
case .invalidCredentials:
return "Invalid email or password"
case .emailNotVerified:
return "Please verify your email address"
case .networkError:
return "Network connection error"
case .unknownError(let message):
return message
}
}
}2. User Feedback
.alert("Error", isPresented: $showError) {
Button("OK") { }
} message: {
Text(errorMessage)
}
.toast(isPresented: $showToast, message: toastMessage, isSuccess: isSuccess)Security Features
1. Input Sanitization
private func sanitizeInput(_ input: String) -> String {
return input.trimmingCharacters(in: .whitespacesAndNewlines)
}
private func validateEmail(_ email: String) -> Bool {
let emailRegex = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,64}"
let emailPredicate = NSPredicate(format:"SELF MATCHES %@", emailRegex)
return emailPredicate.evaluate(with: email)
}2. Password Requirements
private func validatePassword(_ password: String) -> Bool {
return password.count >= 6 &&
password.count <= 12 &&
password.rangeOfCharacter(from: .letters) != nil
}Best Practices
1. User Experience
// Provide immediate feedback
.onChange(of: account) { newValue in
validateInput()
}
// Show loading states
.disabled(isLoading)
.overlay(
ProgressView()
.opacity(isLoading ? 1 : 0)
)2. Accessibility
.accessibilityLabel("Email input field")
.accessibilityHint("Enter your email address")
.accessibilityIdentifier("emailTextField")3. Keyboard Management
.onSubmit {
if isValidInput {
signInWithEmail()
}
}
.submitLabel(.go)Integration with Other Modules
1. Onboarding Integration
// Show onboarding for new users
if authManager.isAuthenticated && !hasCompletedOnboarding {
OnboardingView()
}2. Subscription Integration
// Check subscription status after login
.onReceive(authManager.$isAuthenticated) { isAuthenticated in
if isAuthenticated {
revenueCatManager.checkSubscriptionStatus()
}
}Featured Functions
1. Multi-Authentication Support
- Email/password authentication
- Apple Sign-In integration
- Social login extensibility
2. Real-time Validation
- Input format checking
- Password strength indicators
- Immediate user feedback
3. Smooth User Experience
- Animated transitions
- Loading states
- Toast notifications
4. Security First
- Input sanitization
- Secure password handling
- Session management
The Login and Sign Up module provides a complete, secure, and user-friendly authentication system that integrates seamlessly with the rest of your EasyAppSwiftUI application.
Last updated on