- Apple Sign In - Native iOS authentication
- Google Sign In - OAuth via Google
- Email/Password - Traditional email authentication
Features
Unified Sign In Experience
- Single Sign In Screen: All authentication options on one screen
- Social OAuth: Apple and Google sign in via Supabase Auth
- Email Authentication: Sign up and sign in with email/password
- Password Reset: Forgot password flow via email
Session Persistence
✅ Users stay logged in automatically - No need to sign in every time The app implements robust session persistence:- Keychain Storage: Auth tokens are securely stored in iOS Keychain
- Automatic Session Loading: When the app launches, sessions are restored from Keychain
- Token Validation: Expired sessions are automatically cleared
- Automatic Refresh: Tokens are refreshed 60 seconds before expiry
- Retry Logic: Failed refresh attempts retry up to 3 times with backoff
Session Lifecycle
Setup
1. Configure Supabase
Enable Social Providers
- Go to Supabase Dashboard
- Select your project
- Navigate to Authentication → Providers
- Click Apple
- Toggle Enable Sign in with Apple
- Configure:
- Services ID: Your app’s Bundle ID
- Team ID: Your Apple Developer Team ID
- Key ID: From Apple Developer Portal
- Private Key: Download from Apple Developer Portal
- Click Save
- Click Google
- Toggle Enable Sign in with Google
- Configure:
- Client ID (for OAuth): From Google Cloud Console
- Client Secret: From Google Cloud Console
- Add authorized redirect URIs:
- Click Save
2. Configure iOS App
Update Secrets Configuration:Package.swift:
3. Setup CompositionRoot
The boilerplate comes with auth pre-configured, but here’s how it works:Usage
Sign In Flow
TheSignInView provides a premium, minimal authentication experience:
- Clean, Apple-like aesthetic with generous whitespace
- Native Apple button (HIG compliant) as primary CTA
- Visual hierarchy: Apple → Google → “Use email instead” link
- Premium feel with continuous corner radii and subtle borders
- Adapts to light/dark mode automatically
- Apple Sign In: Native button (HIG compliant) - primary option
- Google Sign In: Secondary button with subtle border
- Email Sign In: Shown via “Use email instead” link (opens sheet)
- Create Account: Accessible from email login sheet
- Forgot Password: Accessible from email login sheet
- Links and accents use
DSColors.accentPrimary(warm pink in Aurora, neutral in others) - Text colors use
DSColors.textPrimaryandDSColors.textSecondary - Backgrounds and surfaces adapt to theme palette
- Icons inherit theme accent color
- No hardcoded system blue - everything theme-aware
SwiftAIBoilerplatePro/AppShell/SignInView.swift:
Spacing & Rhythm:
- Top space:
Spacer().frame(height: 100)- Adjust for vertical positioning - Between hero and buttons:
64pt- Control breathing room - Bottom space:
80ptthen48pt- Legal section padding
- App title:
28pt semibold rounded- Adjust size/weight - Tagline:
15pt regular, 0.3 tracking, 70% opacity- Refine elegance - Legal text:
12pt, 55% opacity- Keep whisper-quiet
- Avatar blur:
blur(radius: 20)on gradient circle - Background: Subtle top-to-bottom gradient
- Google button:
surface.opacity(0.6)with0.5pt border - Link colors: Uses
accentPrimary.opacity(0.7)for cohesion
- Hero fade-in:
.easeOut(duration: 0.6)on appear - Buttons slide:
.delay(0.15)for staggered entrance - Error message:
.spring(response: 0.35)for smooth entry
- Max width:
380ptfor button container (narrower = more refined)
Check Authentication State
Sign Out
- Revoke the access token on the server
- Clear tokens from Keychain
- Clear in-memory session
- Navigate to sign-in screen
How It Works
Apple Sign In Flow
- User taps “Continue with Apple”
- System shows Apple Sign In sheet
- User authenticates with Face ID/Touch ID
- App receives Apple ID token + nonce
- Token is exchanged with Supabase for session
- Session stored in Keychain
- User navigated to main screen
Google Sign In Flow
- User taps “Continue with Google”
- Google Sign In SDK presents OAuth flow
- User selects Google account
- App receives Google ID token
- Token is exchanged with Supabase for session
- Session stored in Keychain
- User navigated to main screen
Email Sign In Flow
- User enters email and password
- Credentials sent to Supabase
- Supabase validates and returns session
- Session stored in Keychain
- User navigated to main screen
Session Persistence Details
How Sessions Are Stored
Sessions are stored in iOS Keychain with the following keys:- Uses
kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly - Data is encrypted by iOS
- Survives app updates
- Deleted on app uninstall
Automatic Session Loading
On app launch (loadInitialSession()):
- Load from Keychain: Attempts to load stored session
- Validate Expiry: Checks if session is expired
- Clear if Invalid: Removes expired sessions
- Refresh if Needed: Proactively refreshes expiring tokens
- Emit State: Notifies observers of auth state
Token Refresh Strategy
The app uses proactive refresh to ensure tokens are always valid:- Schedule Refresh: 60 seconds before token expiry
- Automatic Execution: Refresh happens in background
- Retry Logic: Up to 3 attempts with exponential backoff
- Token Rotation: Handles Supabase refresh token rotation
- Cancellation-Aware: Properly handles task cancellation
Navigation Based on Auth State
TheLaunchRouter automatically handles navigation:
- ✅ Users automatically navigate to main screen when signed in
- ✅ Users automatically navigate to sign in when signed out
- ✅ No manual navigation needed
- ✅ Works for all auth methods (Apple, Google, Email)
Best Practices
Always Check Auth State
Handle Sign Out Gracefully
Use Session Tokens for API Calls
The Networking package automatically includes auth tokens:Troubleshooting
Users Have to Sign In Every Time
Check:- Keychain is accessible (not disabled in Xcode capabilities)
loadInitialSession()is being called- No errors in
SessionManagerinitialization - Check logs for “Loaded session is expired, clearing”
Google Sign In Not Working
- Verify
GOOGLE_CLIENT_IDis set inSecrets.xcconfig - Check Google Cloud Console configuration
- Ensure redirect URIs match exactly
- Verify GoogleSignIn SDK is installed
Apple Sign In Fails
- Check Apple Developer Portal configuration
- Verify Team ID, Key ID, and Private Key are correct
- Ensure “Sign in with Apple” capability is enabled
- Check bundle ID matches Services ID
Token Refresh Fails
Check logs for:- Network connectivity issues
- Supabase service status
- Invalid refresh token (forces re-authentication)
- Too many concurrent refresh attempts
Security Considerations
- Tokens in Keychain: Never store tokens in UserDefaults or files
- HTTPS Only: All auth requests use HTTPS
- Token Expiry: Access tokens expire (default: 1 hour)
- Refresh Rotation: Supabase rotates refresh tokens for security
- Server-Side Validation: Always validate tokens server-side
