SelfieCam/PRD.md

19 KiB

Product Requirements Document (PRD)

SelfieCam - Professional Selfie Camera App

Version: 1.0
Platform: iOS 18.0+
Language: Swift 6 with strict concurrency
Framework: SwiftUI


Executive Summary

SelfieCam is a professional-grade selfie camera app featuring a customizable screen-based ring light overlay, premium camera controls, and beautiful branding. The app targets content creators, makeup artists, video call professionals, and anyone who needs flattering lighting for selfies.


Target Audience

  • Content creators and influencers
  • Makeup artists and beauty professionals
  • Video call and streaming professionals
  • Casual users seeking better selfie lighting
  • Portrait photographers needing on-the-go lighting

Technical Requirements

Platform & Tools

Requirement Specification
iOS Deployment Target iOS 18.0+
Swift Version Swift 6 with strict concurrency checking
UI Framework SwiftUI (primary)
Persistence iCloud via CloudSyncManager
Subscriptions RevenueCat SDK
Camera MijickCamera framework
Design System Bedrock (local package)

Architecture Principles

  1. Protocol-Oriented Programming (POP) - All shared capabilities defined via protocols before concrete types
  2. MVVM-lite - Views are "dumb" renderers; all logic lives in @Observable view models
  3. Bedrock Design System - Centralized design tokens, no magic numbers
  4. Full Accessibility - Dynamic Type, VoiceOver labels/hints/traits/announcements
  5. Modern Swift & SwiftUI - Swift 6 concurrency, @MainActor, modern APIs
  6. Testable & Reusable Design - Protocols enable mocking and future package extraction

Feature Requirements

FR-100: Core Camera System

FR-101: Camera Preview

  • Priority: P0 (Critical)
  • Description: Full-screen camera preview with real-time display
  • Acceptance Criteria:
    • Smooth, low-latency camera preview
    • Supports both front and back camera
    • Camera switching via UI button
    • Prevents screen dimming during camera use
    • Uses MijickCamera framework for SwiftUI-native handling

FR-102: Photo Capture

  • Priority: P0 (Critical)
  • Description: High-quality photo capture with multiple trigger methods
  • Acceptance Criteria:
    • Capture button triggers photo capture
    • Volume buttons trigger capture (hardware shutter)
    • Camera Control button full press triggers capture (iPhone 16+)
    • Post-capture preview with share functionality
    • Auto-save option to Photo Library

FR-103: Zoom Control

  • Priority: P1 (High)
  • Description: Pinch-to-zoom gesture support
  • Acceptance Criteria:
    • Smooth pinch-to-zoom interpolation
    • Zoom level persists during session
    • Zoom resets on camera switch (optional behavior)

FR-104: Camera Control Button Support

  • Priority: P2 (Medium)
  • Description: iPhone 16+ Camera Control button integration
  • Acceptance Criteria:
    • Full press triggers photo capture
    • Light press locks focus/exposure (if API available)
    • Uses AVCaptureEventInteraction (iOS 17.2+)
  • Known Limitations:
    • Light press may be restricted to first-party apps
    • Swipe-to-zoom is Apple-exclusive API

FR-200: Ring Light System

FR-201: Ring Light Overlay

  • Priority: P0 (Critical)
  • Description: Screen-based ring light effect using colored border
  • Acceptance Criteria:
    • Configurable border thickness (10-120pt range)
    • Border renders around camera preview
    • Quick enable/disable toggle
    • Smooth transition animations

FR-202: Ring Light Colors

  • Priority: P0 (Critical)
  • Description: Multiple color temperature presets
  • Free Colors:
    • Pure White
    • Warm Cream
  • Premium Colors:
    • Ice Blue
    • Soft Pink
    • Warm Amber
    • Cool Lavender
  • Acceptance Criteria:
    • Color picker UI with visual swatches
    • Premium colors show lock indicator for free users
    • Premium users can access custom color picker

FR-203: Ring Light Brightness

  • Priority: P1 (High)
  • Description: Adjustable ring light opacity/brightness
  • Acceptance Criteria:
    • Slider control for brightness (10%-100%)
    • Real-time preview of brightness changes
    • Debounced saving (300ms) to prevent excessive iCloud writes

FR-300: Flash System

FR-301: Flash Modes

  • Priority: P1 (High)
  • Description: Multiple flash options for photo capture
  • Modes:
    • Off
    • On
    • Auto
  • Acceptance Criteria:
    • Mode selector in camera UI
    • Flash fires during capture when enabled
    • Auto mode uses ambient light detection

FR-302: Front Flash

  • Priority: P1 (High)
  • Description: Screen brightness-based flash for front camera
  • Acceptance Criteria:
    • Screen brightness increases to maximum during front camera capture
    • Returns to original brightness after capture

FR-303: Flash Sync (Premium)

  • Priority: P2 (Medium)
  • Description: Match flash color with ring light color
  • Acceptance Criteria:
    • Premium feature with appropriate gating
    • Screen color matches current ring light color during flash
    • Toggle in settings to enable/disable

FR-400: Self-Timer System

FR-401: Timer Options

  • Priority: P1 (High)
  • Description: Countdown timer before photo capture
  • Free Options:
    • Off
    • 3 seconds
  • Premium Options:
    • 5 seconds
    • 10 seconds
  • Acceptance Criteria:
    • Visual countdown indicator
    • Audio feedback (optional)
    • Cancel option during countdown
    • VoiceOver announces countdown

FR-500: Display & Enhancement Features

FR-501: Grid Overlay

  • Priority: P2 (Medium)
  • Description: Rule-of-thirds composition guide
  • Acceptance Criteria:
    • Toggle in settings to show/hide
    • Semi-transparent grid lines
    • Does not interfere with tap gestures

FR-502: True Mirror Mode (Premium)

  • Priority: P2 (Medium)
  • Description: Horizontally flipped preview like a real mirror
  • Acceptance Criteria:
    • Premium feature with appropriate gating
    • Live preview is mirrored
    • Captured photo reflects mirror setting

FR-503: Skin Smoothing (Premium)

  • Priority: P2 (Medium)
  • Description: Real-time subtle skin smoothing filter
  • Acceptance Criteria:
    • Premium feature with appropriate gating
    • Toggle in settings
    • Subtle, natural-looking effect
    • Applied to both preview and captured photo

FR-504: Center Stage (Premium)

  • Priority: P3 (Low)
  • Description: Automatic subject tracking/centering
  • Acceptance Criteria:
    • Premium feature with appropriate gating
    • Uses Apple's Center Stage API if available
    • Graceful fallback on unsupported devices

FR-600: Photo Quality Options

FR-601: HDR Mode (Premium)

  • Priority: P2 (Medium)
  • Description: High Dynamic Range photo capture
  • Modes:
    • Off
    • On
    • Auto
  • Acceptance Criteria:
    • Premium feature with appropriate gating
    • HDR indicator in UI when enabled
    • Uses system HDR capture capabilities

FR-602: Photo Quality Settings (Premium)

  • Priority: P2 (Medium)
  • Description: Resolution/quality selection
  • Options:
    • Medium (Free)
    • High (Premium)
  • Acceptance Criteria:
    • Premium feature for High quality
    • Clear indication of current quality setting
    • Maximum resolution output for High setting

FR-700: Settings & Synchronization

FR-701: iCloud Sync

  • Priority: P1 (High)
  • Description: Automatic settings synchronization across devices
  • Acceptance Criteria:
    • Available to all users (free and premium)
    • Real-time sync status with last sync timestamp
    • Manual "Sync Now" option
    • Uses Bedrock's CloudSyncManager

FR-702: Settings Persistence

  • Priority: P0 (Critical)
  • Description: All user preferences stored in SyncedSettings model
  • Settings Include:
    • 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
  • Acceptance Criteria:
    • Settings persist across app launches
    • Debounced saves for slider values
    • Settings sync via iCloud

FR-800: Branding & Launch Experience

FR-801: Animated Launch Screen

  • Priority: P2 (Medium)
  • Description: Beautiful branded launch experience
  • Acceptance Criteria:
    • Animated launch with configurable duration
    • Customizable colors, patterns, and layout
    • Seamless transition to main app
    • Uses Bedrock's LaunchScreenConfig

FR-802: App Icon

  • Priority: P2 (Medium)
  • Description: Consistent branded app icon
  • Acceptance Criteria:
    • Generated via Bedrock icon system
    • Matches launch screen branding
    • Icon generator available in DEBUG builds

FR-900: Premium & Monetization

FR-901: Freemium Model

  • Priority: P0 (Critical)
  • Description: Free tier with optional Pro subscription
  • Free Features:
    • Basic ring light (2 colors)
    • Photo capture
    • 3-second timer
    • Grid overlay
    • Zoom
    • iCloud sync
  • Premium Features:
    • Full color palette + custom colors
    • HDR mode
    • High quality photos
    • Flash sync
    • True mirror mode
    • Skin smoothing
    • Center stage
    • Extended timers (5s, 10s)

FR-902: RevenueCat Integration

  • Priority: P0 (Critical)
  • Description: Subscription management via RevenueCat
  • Acceptance Criteria:
    • PremiumManager wraps RevenueCat SDK
    • PremiumGate utility for consistent feature gating
    • Entitlement named pro
    • Settings automatically fall back to free defaults when not premium

FR-903: Paywall

  • Priority: P1 (High)
  • Description: Pro subscription purchase flow
  • Acceptance Criteria:
    • Clear presentation of premium features
    • Monthly and yearly subscription options
    • Restore purchases functionality
    • Accessible and localized

FR-904: Debug Premium Mode

  • Priority: P3 (Low)
  • Description: Testing premium features without subscription
  • Acceptance Criteria:
    • Environment variable ENABLE_DEBUG_PREMIUM=1
    • Only works in DEBUG builds
    • Unlocks all premium features for testing

Non-Functional Requirements

NFR-100: Accessibility

NFR-101: VoiceOver Support

  • Priority: P0 (Critical)
  • Acceptance Criteria:
    • All interactive elements have meaningful .accessibilityLabel()
    • Dynamic state uses .accessibilityValue()
    • Actions described with .accessibilityHint()
    • Appropriate traits via .accessibilityAddTraits()
    • Decorative elements hidden with .accessibilityHidden(true)
    • Important events trigger accessibility announcements

NFR-102: Dynamic Type

  • Priority: P0 (Critical)
  • Acceptance Criteria:
    • All text supports Dynamic Type
    • Custom dimensions use @ScaledMetric
    • UI remains usable at largest text sizes

NFR-200: Performance

NFR-201: Camera Performance

  • Priority: P0 (Critical)
  • Acceptance Criteria:
    • Smooth, real-time camera preview (30+ fps)
    • Minimal latency on capture
    • No UI blocking during photo processing

NFR-202: Battery Efficiency

  • Priority: P1 (High)
  • Acceptance Criteria:
    • Efficient camera usage
    • Debounced saves reduce iCloud writes
    • Screen dimming prevention is intentional (user is actively using camera)

NFR-300: Privacy & Security

NFR-301: Data Collection

  • Priority: P0 (Critical)
  • Acceptance Criteria:
    • No data collection
    • No analytics
    • No tracking
    • Privacy policy reflects minimal data usage

NFR-302: API Key Security

  • Priority: P0 (Critical)
  • Acceptance Criteria:
    • API keys stored in .xcconfig files
    • Secrets.xcconfig is gitignored
    • Template file provided for setup

NFR-400: Localization

NFR-401: String Catalogs

  • Priority: P1 (High)
  • Acceptance Criteria:
    • Uses .xcstrings files for localization
    • All user-facing strings in String Catalog
    • Minimum supported languages: English (en), Spanish-Mexico (es-MX), French-Canada (fr-CA)

Project Structure

SelfieCam/
├── App/                              # App entry point with launch screen
├── Configuration/                    # xcconfig files (API keys)
├── Features/
│   ├── Camera/                       # Main camera UI
│   │   ├── ContentView.swift         # Main screen coordinator
│   │   ├── Views/                    # Camera UI components
│   │   │   ├── CustomCameraScreen.swift
│   │   │   ├── RingLightOverlay.swift
│   │   │   ├── CaptureButton.swift
│   │   │   ├── ExpandableControlsPanel.swift
│   │   │   ├── CaptureEventInteraction.swift
│   │   │   └── ...
│   │   ├── GridOverlay.swift
│   │   └── PostCapturePreviewView.swift
│   ├── Paywall/                      # Pro subscription flow
│   │   └── ProPaywallView.swift
│   └── Settings/                     # Configuration screens
│       ├── SettingsView.swift
│       ├── SettingsViewModel.swift
│       └── ...
├── Shared/
│   ├── BrandingConfig.swift          # App icon & launch screen config
│   ├── DesignConstants.swift         # Design tokens (uses Bedrock)
│   ├── Color+Extensions.swift        # Ring light color presets
│   ├── Models/                       # Data models
│   │   ├── CameraFlashMode.swift
│   │   ├── CameraHDRMode.swift
│   │   ├── PhotoQuality.swift
│   │   └── ...
│   ├── Protocols/                    # Shared protocols
│   │   ├── RingLightConfigurable.swift
│   │   ├── CaptureControlling.swift
│   │   ├── CaptureEventHandling.swift
│   │   └── PremiumManaging.swift
│   ├── Premium/                      # Subscription management
│   │   └── PremiumManager.swift
│   ├── Services/                     # App services
│   │   └── PhotoLibraryService.swift
│   └── Storage/                      # Persistence
│       └── SyncedSettings.swift
└── Resources/                        # Assets, localization
    ├── Assets.xcassets/
    │   ├── AppIcon.appiconset/
    │   ├── LaunchBackground.colorset/
    │   └── ...
    └── Localizable.xcstrings

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

Premium Feature Gating Pattern

All premium features use centralized PremiumGate utility:

// Getter pattern - returns free default if not premium
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 Feature Matrix

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

Known Limitations

Camera Control Button Light Press

Status: Not Working - Needs Investigation

The Camera Control button (iPhone 16+) full press works for photo capture, but the light press (secondary action) does not work.

What Works:

  • Camera Control full press → triggers photo capture
  • Volume up/down → triggers capture

What Doesn't Work:

  • Camera Control light press → no event received
  • Camera Control swipe gestures (zoom) → Apple-exclusive API

Possible Causes:

  1. Light press may be restricted to first-party apps
  2. MijickCamera session may interfere with light press detection
  3. Accessibility settings may need explicit enablement

User Workaround: Check Settings > Accessibility > Camera Control:

  • Ensure Camera Control is enabled
  • Ensure Light-Press is turned ON
  • Adjust Light-Press Force if needed

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
  • Camera Control button swipe-to-zoom (if Apple makes API public)

Required Permissions

Permission Reason
Camera Photo preview and capture
Photo Library Save captured photos
Microphone May be requested by camera framework (not actively used)
iCloud Settings synchronization (optional)

Development Setup

1. Clone and Configure

git clone https://github.com/yourusername/SelfieCam.git
cd SelfieCam
cp SelfieCam/Configuration/Secrets.xcconfig.template SelfieCam/Configuration/Secrets.xcconfig

2. Add API Key

Edit Secrets.xcconfig:

REVENUECAT_API_KEY = appl_your_actual_api_key_here

3. RevenueCat Setup

  1. Create RevenueCat account and project
  2. Connect to App Store Connect
  3. Create products and entitlement named pro
  4. Copy Public App-Specific API Key to Secrets.xcconfig

4. Test Premium Features

Set environment variable in scheme:

  • Name: ENABLE_DEBUG_PREMIUM
  • Value: 1

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, PRD

This PRD serves as the primary requirements document for SelfieCam development.