# 30. iOS App — Authentication, Onboarding, and Account Setup meta: id: shieldai-unified-restructure-30 feature: shieldai-unified-restructure priority: P1 depends_on: [shieldai-unified-restructure-28, shieldai-unified-restructure-29] tags: [ios, swiftui, auth, onboarding, mobile] objective: - Build the authentication and onboarding flow for the iOS app: login, signup, password reset, and a multi-step onboarding experience. Use native iOS authentication where possible (Sign in with Apple) and maintain visual consistency with the web app. deliverables: - `iOS/ShieldAI/Views/Auth/AuthView.swift` — Auth container: - Switches between login and signup modes - ShieldAI branding at top - Social auth buttons (Sign in with Apple, Google) - `iOS/ShieldAI/Views/Auth/LoginView.swift` — Login screen: - Email and password fields using `ShieldTextField` - "Remember me" toggle - "Forgot password?" link - "Sign In" `ShieldButton` - "Don't have an account? Sign up" link - `iOS/ShieldAI/Views/Auth/SignupView.swift` — Signup screen: - Name, email, password, confirm password fields - Password strength indicator - Terms of service agreement toggle - "Create Account" button - `iOS/ShieldAI/Views/Auth/ForgotPasswordView.swift` — Password reset: - Email input + submit - Success state with instructions - `iOS/ShieldAI/Views/Onboarding/OnboardingView.swift` — Onboarding flow: - Page-based `TabView` with 4 steps - Step 1: Welcome + plan selection (Basic, Plus, Premium cards) - Step 2: Add first watchlist item (email or phone) - Step 3: Invite family members (optional) - Step 4: Setup complete → transition to main app - `iOS/ShieldAI/Views/Auth/BiometricAuthView.swift` — Face ID / Touch ID prompt: - Triggered after first successful login - Uses `LocalAuthentication` framework - Stores preference in Keychain - `iOS/ShieldAI/Services/AuthService.swift` — Auth business logic: - `login(email, password)` → calls API (task 31) - `signup(name, email, password)` → calls API - `resetPassword(email)` → calls API - `signInWithApple()` → handles Apple ID credential - `signInWithGoogle()` → handles Google Sign-In - `enableBiometricAuth()` → stores credential in Keychain - `logout()` → clears tokens and Keychain steps: 1. Create `iOS/ShieldAI/Views/Auth/` and `iOS/ShieldAI/Views/Onboarding/` directories. 2. **AuthView**: - Use `@State` to toggle between login and signup - Show ShieldAI logo and tagline at top - Use `ShieldCard` for the form container 3. **LoginView**: - `ShieldTextField` for email and password - `Toggle` for "Remember me" - `ShieldButton` for submit - Link to ForgotPasswordView - On success: store JWT in Keychain, navigate to main app or onboarding 4. **SignupView**: - Additional fields: name, confirm password - Password strength: check length, uppercase, number, special char - Visual strength bar using `ShieldProgressBar` - Terms toggle (required) - On success: store JWT, show onboarding 5. **ForgotPasswordView**: - Simple email field + submit - Success message: "Check your email for reset instructions" 6. **OnboardingView**: - `TabView` with `.tabViewStyle(.page)` for swipeable steps - Step 1: Plan cards with feature lists, highlight recommended tier - Step 2: Input for email/phone, "Add" button, shows added items list - Step 3: Email inputs for family invites, "Skip" button - Step 4: Success animation (checkmark), "Get Started" button - Progress dots at bottom showing current step 7. **BiometricAuthView**: - `LAContext` for Face ID / Touch ID evaluation - On success: store "useBiometric" preference and credential in Keychain - On failure: fall back to password 8. **AuthService**: - Protocol-based for testability - Implementation calls API client (task 31) - Keychain wrapper for secure token storage - Apple Sign-In: use `AuthenticationServices` framework (`ASAuthorizationAppleIDButton`) - Google Sign-In: use `GoogleSignIn` SDK 9. Wire auth state to root view: - `ContentView` observes `AuthService.isAuthenticated` - On logout: clear state and show AuthView steps: - Unit: AuthService stores and retrieves tokens from Keychain - Unit: Password strength calculator returns correct level - Unit: Onboarding stepper advances and collects data - Integration: Sign in with Apple button triggers ASAuthorizationController - E2E: Complete login → onboarding → main app flow acceptance_criteria: - [ ] Login screen accepts email/password and authenticates via API - [ ] Signup screen validates inputs and creates account via API - [ ] Password reset flow sends request to API and shows success state - [ ] Onboarding has 4 steps with progress indicator and swipe navigation - [ ] Sign in with Apple button works and authenticates user - [ ] Biometric auth (Face ID/Touch ID) can be enabled after first login - [ ] Tokens are stored securely in iOS Keychain - [ ] Logout clears all auth state and returns to login screen - [ ] Auth flow matches web app visual style validation: - Run app on simulator, complete login with test credentials - Verify JWT stored in Keychain (use Keychain utility or debug print) - Test Sign in with Apple flow (simulator supports mock Apple ID) - Complete onboarding and verify data sent to API - Test Face ID prompt on device (simulator can simulate with Features menu) - Run unit tests via Xcode Cmd+U notes: - Sign in with Apple is required for App Store approval if you offer other third-party sign-in options. - Use `ASAuthorizationController` for Apple Sign-In. Handle both `.signIn` and `.credentialRevokedNotification`. - For Google Sign-In, the `GoogleSignIn` SDK requires a `GoogleService-Info.plist`. Add setup instructions to README. - Keychain token storage should use `kSecAttrAccessibleWhenUnlockedThisDeviceOnly` for security. - The onboarding data (plan, watchlist items, family invites) should be collected in a local model and submitted to the API at the final step (or incrementally). - Consider using SwiftUI's `.fullScreenCover` for the auth flow so it covers the entire screen without tab bar.