SelfieCam/AI_Implementation.md

8.9 KiB

AI Implementation Guide

How This App Was Architected & Built

This project was developed following strict senior-level iOS engineering standards, with guidance from AI assistants acting as Senior iOS Engineers specializing in SwiftUI and modern Apple frameworks.


Guiding Principles (from AGENTS.md)

  • Protocol-Oriented Programming (POP) first: All shared capabilities defined via protocols before concrete types
  • MVVM-lite: Views are "dumb" — all logic lives in @Observable view models
  • Bedrock Design System: Centralized design tokens, no magic numbers
  • Full accessibility: Dynamic Type, VoiceOver labels/hints/traits/announcements
  • Modern Swift & SwiftUI: Swift 6 concurrency, @MainActor, foregroundStyle, clipShape(.rect), NavigationStack
  • Testable & reusable design: Protocols enable mocking and future package extraction

Architecture Overview

Shared/
├── DesignConstants.swift           → Uses Bedrock design tokens
├── BrandingConfig.swift            → App icon & launch screen config
├── Color+Extensions.swift          → Ring light color presets
├── Models/
│   ├── CameraFlashMode.swift       → Flash mode enum
│   ├── CameraHDRMode.swift         → HDR mode enum  
│   ├── PhotoQuality.swift          → Photo quality settings
│   └── CapturedPhoto.swift         → Photo data model
├── Protocols/
│   ├── RingLightConfigurable.swift → Border, color, brightness
│   ├── CaptureControlling.swift    → Timer, grid, zoom, capture
│   └── PremiumManaging.swift       → Subscription state
├── Premium/
│   └── PremiumManager.swift        → RevenueCat integration
├── Services/
│   └── PhotoLibraryService.swift   → Photo saving service
└── Storage/
    └── SyncedSettings.swift        → iCloud-synced settings

Features/
├── Camera/                         → Main camera UI
│   ├── ContentView.swift           → Screen coordinator
│   ├── Views/                      → UI components
│   └── GridOverlay.swift           → Rule of thirds
├── Settings/                       → Configuration
│   ├── SettingsView.swift          → Settings UI
│   └── SettingsViewModel.swift     → Settings logic + sync
└── Paywall/                        → Pro subscription flow

Key Implementation Decisions

1. Ring Light Effect

  • Achieved using RingLightOverlay view that creates a colored border around the camera preview
  • Border width controlled via user setting (10-120pt range)
  • Multiple preset colors with premium custom color picker
  • Adjustable opacity/brightness (10%-100%)
  • Enabled/disabled toggle for quick access

2. Camera System

  • Uses MijickCamera framework for SwiftUI-native camera handling
  • Supports front and back camera switching
  • Pinch-to-zoom with smooth interpolation
  • Flash modes: Off, On, Auto (with premium flash sync)
  • HDR mode support (premium feature)
  • Photo quality settings (medium free, high premium)

3. Capture Enhancements

  • Self-timer with countdown (3s free, 5s/10s premium)
  • Post-capture preview with share functionality
  • Auto-save option to Photo Library
  • Front flash using screen brightness

4. Freemium Model

  • Built with RevenueCat for subscription management
  • PremiumManager wraps RevenueCat SDK
  • PremiumGate utility for clean premium feature access
  • Settings automatically fall back to free defaults when not premium

5. iCloud Sync

  • Uses Bedrock's CloudSyncManager for settings synchronization
  • SyncedSettings model contains all user preferences
  • Debounced saves for slider values (300ms delay)
  • Real-time sync status display in Settings
  • Available to all users (not a premium feature)

6. Branding System

  • Uses Bedrock's Branding module for launch screen and app icon
  • BrandingConfig.swift defines app-specific colors and symbols
  • LaunchBackground.colorset matches launch screen primary color
  • Animated launch with configurable duration and pattern style
  • Icon generator available in DEBUG builds

Premium Feature Implementation

How Premium Gating Works

The app uses a centralized PremiumGate utility for consistent premium feature handling:

// In SettingsViewModel
var isMirrorFlipped: Bool {
    get { PremiumGate.get(cloudSync.data.isMirrorFlipped, default: false, isPremium: isPremiumUnlocked) }
    set { 
        guard PremiumGate.canSet(isPremium: isPremiumUnlocked) else { return }
        updateSettings { $0.isMirrorFlipped = newValue } 
    }
}

Premium Features List

Feature Free Value Premium Value
Ring light colors Pure White, Warm Cream All presets + custom
Timer options Off, 3s Off, 3s, 5s, 10s
Photo quality Medium Medium, High
HDR mode Off Off, On, Auto
True mirror Off Configurable
Skin smoothing Off Configurable
Flash sync Off Configurable
Center stage Off Configurable

Settings & Persistence

SyncedSettings Model

All user preferences are stored in a single SyncedSettings struct that syncs via iCloud:

  • Ring light: size, color ID, custom color RGB, opacity, enabled
  • Camera: position, flash mode, HDR mode, photo quality
  • Display: mirror flip, skin smoothing, grid visible
  • Capture: timer, capture mode, auto-save
  • Premium features: flash sync, center stage

Debounced Saves

Slider values (ring size, opacity) use debounced saving to prevent excessive iCloud writes:

private func debouncedSave(key: String, action: @escaping () -> Void) {
    debounceTask?.cancel()
    debounceTask = Task {
        try? await Task.sleep(for: .milliseconds(300))
        guard !Task.isCancelled else { return }
        action()
    }
}

Branding Implementation

Files Involved

  1. BrandingConfig.swift - Defines app icon and launch screen configurations
  2. LaunchBackground.colorset - Asset catalog color matching primary brand color
  3. SelfieCamApp.swift - Wraps ContentView with AppLaunchView

Color Scheme

extension Color {
    enum Branding {
        static let primary = Color(red: 0.85, green: 0.25, blue: 0.45)   // Vibrant magenta
        static let secondary = Color(red: 0.45, green: 0.12, blue: 0.35) // Deep purple
        static let accent = Color.white
    }
}

Launch Screen Configuration

static let selfieCam = LaunchScreenConfig(
    title: "SELFIE CAM",
    tagline: "Look Your Best",
    iconSymbols: ["camera.fill", "sparkles"],
    cornerSymbol: "sparkle",
    patternStyle: .radial,
    // ... colors and sizing
)

Development Workflow

Adding a New Feature

  1. Define the protocol (if shared behavior)
  2. Add to SyncedSettings (if needs persistence)
  3. Implement in SettingsViewModel (with premium gating if applicable)
  4. Add UI in SettingsView
  5. Update documentation (README, this file)

Adding a Premium Feature

  1. Add setting to SyncedSettings with appropriate default
  2. Use PremiumGate.get() for the getter with free default
  3. Use PremiumGate.canSet() guard for the setter
  4. Add premium indicator (crown icon) in UI
  5. Wire up paywall trigger for non-premium users

Testing Premium Features

Set environment variable in scheme:

  • Name: ENABLE_DEBUG_PREMIUM
  • Value: 1

Reusability & Extraction

The codebase is structured for future extraction into reusable packages:

Potential Package Contents
SelfieCameraKit Camera views, capture logic, preview components
RingLightKit Ring light overlay, color presets, configuration
PremiumKit Premium manager, gating utilities, paywall
SyncedSettingsKit CloudSyncManager, settings model pattern

Key Dependencies

Dependency Purpose Integration
Bedrock Design system, branding, cloud sync Local Swift package
MijickCamera Camera capture and preview SPM dependency
RevenueCat Subscription management SPM dependency

Code Quality Standards

  • No magic numbers: All values from Design constants
  • Full accessibility: Every interactive element has VoiceOver support
  • Protocol-first: Shared behavior defined via protocols
  • Separation of concerns: Views are dumb, ViewModels contain logic
  • Modern APIs: Swift 6, async/await, @Observable
  • Documentation: Code comments, README, implementation guides

Future Enhancements

Potential areas for expansion:

  • Real-time filters (beauty, color grading)
  • Gesture-based capture (smile detection)
  • Widget for quick camera access
  • Apple Watch remote trigger
  • Export presets (aspect ratios, watermarks)
  • Social sharing integrations

This architecture demonstrates production-quality SwiftUI development while delivering a polished, competitive user experience.