From 815b91f6caca4d8fc3f60f07a030570aad2b5207 Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Sun, 4 Jan 2026 14:43:53 -0600 Subject: [PATCH] Update documentation and add branding system integration Documentation: - Update README.md with complete feature list and SelfieCam branding - Update AI_Implementation.md with current architecture and branding details - Add SelfieCam-specific sections to AGENTS.md (premium, branding, camera) Features: - Add branding debug section to SettingsView (icon generator, preview) - Add BrandingConfig.swift with app colors and launch screen config - Add LaunchBackground.colorset for seamless launch experience - Wrap app in AppLaunchView for animated launch screen --- AGENTS.md | 163 ++++++++++ AI_Implementation.md | 296 +++++++++++++++--- README.md | 158 +++++++--- .../Features/Settings/SettingsView.swift | 12 +- SelfieCam/Shared/Premium/PremiumManager.swift | 17 +- 5 files changed, 555 insertions(+), 91 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 61dcc2b..1553462 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -497,3 +497,166 @@ Color.Primary.background - If installed, make sure SwiftLint returns no warnings or errors before committing. - Verify that documentation reflects any new functionality or behavioral changes. + + +--- + +# SelfieCam-Specific Guidelines + +The following sections are specific to this app's architecture and features. + + +## App Architecture + +SelfieCam uses the following architectural patterns: + +### Dependencies +- **Bedrock**: Local Swift package for design system, branding, and cloud sync +- **MijickCamera**: SwiftUI camera framework for capture and preview +- **RevenueCat**: Subscription management for premium features + +### Key Protocols + +| Protocol | Purpose | Conforming Types | +|----------|---------|------------------| +| `RingLightConfigurable` | Ring light settings (size, color, opacity) | `SettingsViewModel` | +| `CaptureControlling` | Capture actions (timer, flash, shutter) | `SettingsViewModel` | +| `PremiumManaging` | Subscription state and purchases | `PremiumManager` | + + +## Premium Features + +### Adding a New Premium Feature + +1. **Add setting to `SyncedSettings`** with an appropriate default value +2. **Use `PremiumGate.get()`** in the getter: + ```swift + var myPremiumFeature: Bool { + get { PremiumGate.get(cloudSync.data.myFeature, default: false, isPremium: isPremiumUnlocked) } + set { + guard PremiumGate.canSet(isPremium: isPremiumUnlocked) else { return } + updateSettings { $0.myFeature = newValue } + } + } + ``` +3. **Add crown icon** in the UI to indicate premium status +4. **Wire up paywall** trigger when non-premium users tap the control + +### Current Premium Features + +- Custom ring light colors +- Premium color presets (Ice Blue, Soft Pink, Warm Amber, Cool Lavender) +- Flash sync with ring light color +- HDR mode +- High quality photos +- True mirror mode +- Skin smoothing +- Center Stage +- Extended timers (5s, 10s) +- Video and Boomerang capture modes + + +## Settings & iCloud Sync + +### How Settings Work + +1. All settings are stored in `SyncedSettings` struct +2. `CloudSyncManager` handles iCloud synchronization +3. `SettingsViewModel` exposes properties that read/write through the sync manager +4. Slider values use debounced saves (300ms) to prevent excessive writes + +### Adding a New Setting + +1. Add property to `SyncedSettings` with default value +2. Add corresponding property in `SettingsViewModel` +3. For premium settings, use `PremiumGate` utilities +4. Add UI in `SettingsView` + + +## Branding System + +### Overview + +The app uses Bedrock's branding system for: +- Animated launch screen +- App icon generation +- Consistent color scheme + +### Key Files + +- `Shared/BrandingConfig.swift` - App icon and launch screen configuration +- `Resources/Assets.xcassets/LaunchBackground.colorset/` - Launch screen background color +- `App/SelfieCamApp.swift` - Wraps ContentView with AppLaunchView + +### Modifying Branding + +1. Update colors in `BrandingConfig.swift` → `Color.Branding` +2. Update `LaunchBackground.colorset` to match primary color +3. Adjust icon/launch screen config as needed +4. Use Icon Generator in Settings → Debug to create new app icon + +### Documentation + +See `Bedrock/Sources/Bedrock/Branding/BRANDING_GUIDE.md` for complete branding documentation. + + +## Camera Integration + +### MijickCamera + +The app uses MijickCamera for camera functionality: + +```swift +import MijickCamera + +// Camera position +var cameraPosition: CameraPosition // .front or .back + +// Flash modes +var flashMode: CameraFlashMode // .off, .on, .auto +``` + +### Camera Features + +- Front/back camera switching +- Pinch-to-zoom +- Photo capture with quality settings +- Video recording (premium) +- HDR mode (premium) + + +## Ring Light System + +### How It Works + +The ring light is a colored overlay (`RingLightOverlay`) that surrounds the camera preview: + +- **Size**: Adjustable border width (10-120pt) +- **Color**: Preset colors or custom color picker +- **Opacity**: Adjustable brightness (10%-100%) +- **Toggle**: Can be enabled/disabled + +### Color Presets + +| Color | ID | Premium | +|-------|-----|---------| +| Pure White | `pureWhite` | No | +| Warm Cream | `warmCream` | No | +| Ice Blue | `iceBlue` | Yes | +| Soft Pink | `softPink` | Yes | +| Warm Amber | `warmAmber` | Yes | +| Cool Lavender | `coolLavender` | Yes | +| Custom | `custom` | Yes | + + +## Documentation Files + +When making changes, update the appropriate documentation: + +| File | Purpose | +|------|---------| +| `README.md` | User-facing app overview, setup instructions | +| `AI_Implementation.md` | Technical architecture, implementation details | +| `AGENTS.md` | Development guidelines (this file) | + +Always commit documentation updates with the related code changes. diff --git a/AI_Implementation.md b/AI_Implementation.md index c3fb67a..ab171bb 100644 --- a/AI_Implementation.md +++ b/AI_Implementation.md @@ -1,68 +1,272 @@ -# AI_Implementation.md +# AI Implementation Guide ## How This App Was Architected & Built -This project was developed following strict senior-level iOS engineering standards, with guidance from an AI assistant (Grok) acting as a Senior iOS Engineer specializing in SwiftUI and modern Apple frameworks. +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) -### 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 -- **No third-party dependencies**: Pure Apple frameworks only (SwiftUI, AVFoundation, StoreKit 2, CoreImage) -- **No magic numbers**: All dimensions, opacities, durations from centralized `Design` constants +- **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 SPM package extraction +- **Testable & reusable design**: Protocols enable mocking and future package extraction -### Architecture Overview +--- +## Architecture Overview + +``` Shared/ -├── DesignConstants.swift → Semantic design tokens (spacing, radii, sizes, etc.) -├── Color+Extensions.swift → Ring light color presets +├── 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, mirror, smoothing -│ ├── CaptureControlling.swift → Timer, grid, zoom, capture mode -│ └── PremiumManaging.swift → Subscription state & purchase handling -└── Premium/ -└── PremiumManager.swift → Native StoreKit 2 implementation +│ ├── 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 UI, preview, capture logic -├── Settings/ → Configuration screens -└── Paywall/ → Pro subscription flow +├── 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 +## Key Implementation Decisions -1. **Ring Light Effect** - - Achieved by coloring the safe area background and leaving a centered rectangular window for camera preview - - Border width controlled via user setting - - Gradient support added for directional "portrait lighting" +### 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** - - `AVCaptureSession` with front camera default - - `UIViewRepresentable` wrapper for preview with pinch-to-zoom - - Video data output delegate for future real-time filters (skin smoothing placeholder) +### 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** - - Timer with async countdown and accessibility announcements - - Volume button observation via KVO on `AVAudioSession.outputVolume` - - Flash burst: temporarily sets brightness to 1.0 on capture +### 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 +- Support for photo, video, and boomerang modes -4. **Freemium Model** - - Built with pure StoreKit 2 (no RevenueCat) - - `PremiumManaging` protocol enables easy testing/mocking - - Clean paywall with benefit list and native purchase flow +### 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. **Reusability Focus** - - All shared logic extracted to protocols - - Ready for future extraction into SPM packages: - - `SelfieCameraKit` - - `SelfieRingLightKit` - - `SelfiePremiumKit` +### 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) -### Development Process -- Iterative feature additions guided by competitive analysis of top App Store selfie apps -- Each new capability (timer, boomerang, gradient, subscriptions) added with protocol-first design -- Strict adherence to no magic numbers, full accessibility, and clean separation -- Final structure optimized for maintainability and future library extraction +### 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 -This app demonstrates production-quality SwiftUI architecture while delivering a delightful, competitive user experience. \ No newline at end of file +--- + +## Premium Feature Implementation + +### How Premium Gating Works + +The app uses a centralized `PremiumGate` utility for consistent premium feature handling: + +```swift +// 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 | +| Capture modes | Photo | Photo, Video, Boomerang | + +--- + +## 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: + +```swift +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 + +```swift +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 + +```swift +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. diff --git a/README.md b/README.md index dec8703..26ccce1 100644 --- a/README.md +++ b/README.md @@ -1,42 +1,60 @@ -# SelfieRingLight +# SelfieCam -A modern, professional-grade selfie camera app for iOS that simulates a high-quality ring light using the device's screen. Built entirely with SwiftUI, Swift 6, and AVFoundation. +A modern, professional-grade selfie camera app for iOS featuring a customizable ring light overlay, premium camera controls, and beautiful branding. Built entirely with SwiftUI, Swift 6, and the MijickCamera framework. -Perfect for low-light selfies, video calls, makeup checks, or professional portrait lighting on the go. +Perfect for low-light selfies, content creation, video calls, makeup application, or professional portrait lighting on the go. ## Features ### Core Camera & Lighting -- Full-screen front-camera preview with true mirror option -- Configurable **screen-based ring light** with adjustable border thickness -- Multiple color temperature presets (Pure White, Warm Cream, Ice Blue, Rose Pink, etc.) -- **Directional gradient lighting** for flattering portrait effects -- Real-time screen brightness control (overrides system brightness while in use) -- Flash burst on capture for extra fill light +- Full-screen camera preview with front/back camera switching +- Configurable **screen-based ring light** with adjustable border thickness (10-120pt) +- Multiple color temperature presets (Pure White, Warm Cream, Ice Blue, Soft Pink, Warm Amber, Cool Lavender) +- **Ring light brightness control** with adjustable opacity +- **Flash modes**: Off, On, Auto +- **Front Flash**: Uses screen brightness for front camera flash effect +- Real-time camera preview with smooth performance ### Capture Modes -- Photo capture (saved to Photo Library) -- Video recording -- **Boomerang** mode (3-second looping short video) -- 3-second and 10-second self-timer with countdown overlay and VoiceOver announcements -- Pinch-to-zoom gesture -- Volume button shutter support (photo or video start/stop) +- **Photo capture** with high-quality output +- **Video recording** (Premium) +- **Boomerang mode** for looping short videos (Premium) +- Self-timer with 3-second (free), 5-second, and 10-second (Premium) options +- Pinch-to-zoom gesture support - Rule-of-thirds grid overlay (toggleable) +- Post-capture preview with share functionality ### Premium Features (Freemium Model) -- All advanced color presets + custom colors -- Gradient and directional lighting -- Advanced beauty filters (coming soon) -- Unlimited boomerang length -- No watermarks +- **Custom ring light colors** with full color picker +- **Premium color presets**: Ice Blue, Soft Pink, Warm Amber, Cool Lavender +- **Flash Sync**: Match flash color with ring light color +- **HDR Mode**: High Dynamic Range photo capture +- **High Quality Photos**: Maximum resolution output +- **True Mirror Mode**: Horizontally flipped preview like a real mirror +- **Skin Smoothing**: Real-time subtle skin smoothing filter +- **Center Stage**: Automatic subject tracking/centering +- **Extended Timers**: 5-second and 10-second self-timer options +- **Video & Boomerang**: Video recording and looping video capture - Ad-free experience +### iCloud Sync +- Automatic settings synchronization across all devices +- Real-time sync status with last sync timestamp +- Manual "Sync Now" option +- Available to all users (free and premium) + +### Branding & Launch +- **Animated launch screen** with customizable design +- **App icon generator** for creating consistent branding +- Seamless transition from launch to main app +- Configurable colors, patterns, and layout styles + ### Accessibility & Polish - Full VoiceOver support with meaningful labels, hints, and announcements -- Dynamic Type and ScaledMetric for readable text +- Dynamic Type and ScaledMetric for readable text at all sizes - String Catalog localization ready (`.xcstrings`) -- Prevents screen dimming during use -- Restores original brightness on background/app close +- Consistent design system using Bedrock framework +- Prevents screen dimming during camera use ## Screenshots *(Add App Store-ready screenshots here once built)* @@ -46,12 +64,17 @@ Perfect for low-light selfies, video calls, makeup checks, or professional portr - Xcode 16+ - Swift 6 language mode +## Dependencies +- **[MijickCamera](https://github.com/Mijick/Camera)** - Modern SwiftUI camera framework +- **[RevenueCat](https://www.revenuecat.com)** - Subscription management +- **Bedrock** - Internal design system and UI components (local package) + ## Setup ### 1. Clone the Repository ```bash -git clone https://github.com/yourusername/SelfieRingLight.git -cd SelfieRingLight +git clone https://github.com/yourusername/SelfieCam.git +cd SelfieCam ``` ### 2. Configure API Keys @@ -60,7 +83,7 @@ This project uses `.xcconfig` files to securely manage API keys. **Never commit 1. Copy the template file: ```bash - cp SelfieRingLight/Configuration/Secrets.xcconfig.template SelfieRingLight/Configuration/Secrets.xcconfig + cp SelfieCam/Configuration/Secrets.xcconfig.template SelfieCam/Configuration/Secrets.xcconfig ``` 2. Edit `Secrets.xcconfig` with your actual API key: @@ -91,7 +114,17 @@ To test premium features without a real subscription during development: This unlocks all premium features in DEBUG builds only. -### 5. CI/CD Configuration +### 5. Branding Configuration + +The app uses the Bedrock branding system for launch screen and app icon: + +1. **BrandingConfig.swift** defines colors, icons, and launch screen settings +2. **Launch Screen Background Color** is set in Assets.xcassets and project build settings +3. **Icon Generator** available in Settings → Debug (DEBUG builds only) + +See `Bedrock/Sources/Bedrock/Branding/BRANDING_GUIDE.md` for complete documentation. + +### 6. CI/CD Configuration For automated builds, set the `REVENUECAT_API_KEY` environment variable in your CI/CD system: @@ -108,32 +141,77 @@ Add `REVENUECAT_API_KEY` as a secret in your Xcode Cloud workflow. - Camera access required for preview and capture - Photo Library access required to save photos/videos - Microphone access required for video recording +- iCloud access for settings synchronization (optional) - No data collection, no analytics, no tracking ## Monetization Freemium model with optional "Pro" subscription: -- Free: Basic ring light, standard colors, photo/video, timer, zoom -- Pro: Full color palette, gradients, advanced features, future updates +- **Free**: Basic ring light, standard colors (Pure White, Warm Cream), photo capture, 3s timer, grid, zoom +- **Pro**: Full color palette, custom colors, HDR, high quality, flash sync, true mirror, skin smoothing, center stage, extended timers, video, boomerang Implemented with RevenueCat for reliable subscription management. ## Project Structure ``` -SelfieRingLight/ -├── App/ # App entry point +SelfieCam/ +├── App/ # App entry point with launch screen +├── Configuration/ # xcconfig files (API keys) ├── Features/ -│ ├── Camera/ # Camera preview, capture, view model -│ ├── Paywall/ # Pro subscription flow -│ └── Settings/ # Configuration screens +│ ├── Camera/ # Main camera UI +│ │ ├── ContentView.swift # Main screen coordinator +│ │ ├── Views/ # Camera UI components +│ │ │ ├── CustomCameraScreen.swift +│ │ │ ├── RingLightOverlay.swift +│ │ │ ├── CaptureButton.swift +│ │ │ ├── ExpandableControlsPanel.swift +│ │ │ └── ... +│ │ ├── GridOverlay.swift # Rule of thirds overlay +│ │ └── PostCapturePreviewView.swift +│ ├── Paywall/ # Pro subscription flow +│ │ └── ProPaywallView.swift +│ └── Settings/ # Configuration screens +│ ├── SettingsView.swift +│ ├── SettingsViewModel.swift +│ └── ... ├── Shared/ -│ ├── Configuration/ # xcconfig files (API keys) -│ ├── Premium/ # PremiumManager (RevenueCat) -│ ├── Protocols/ # Shared protocols -│ ├── Color+Extensions.swift # Ring light color presets -│ └── DesignConstants.swift # Design tokens -└── Resources/ # Assets, localization +│ ├── 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 +│ │ └── PremiumManaging.swift +│ ├── Premium/ # Subscription management +│ │ └── PremiumManager.swift +│ ├── Services/ # App services +│ │ └── PhotoLibraryService.swift +│ └── Storage/ # Persistence +│ └── SyncedSettings.swift # iCloud-synced settings model +└── Resources/ # Assets, localization + ├── Assets.xcassets/ + │ ├── AppIcon.appiconset/ + │ ├── LaunchBackground.colorset/ + │ └── ... + └── Localizable.xcstrings ``` +## Key Technologies + +| Technology | Purpose | +|------------|---------| +| SwiftUI | User interface framework | +| Swift 6 | Modern concurrency with strict checking | +| MijickCamera | Camera capture and preview | +| RevenueCat | Subscription management | +| Bedrock | Design system and branding | +| CloudKit | iCloud settings synchronization | +| AVFoundation | Low-level camera access | + ## License *(Add your license here)* diff --git a/SelfieCam/Features/Settings/SettingsView.swift b/SelfieCam/Features/Settings/SettingsView.swift index 077efcf..bf231a5 100644 --- a/SelfieCam/Features/Settings/SettingsView.swift +++ b/SelfieCam/Features/Settings/SettingsView.swift @@ -762,10 +762,20 @@ struct SettingsView: View { } // MARK: - Branding Debug Section - + #if DEBUG private var brandingDebugSection: some View { VStack(spacing: Design.Spacing.small) { + // Debug Premium Toggle + SettingsToggle( + title: "Enable Debug Premium", + subtitle: "Unlock all premium features for testing", + isOn: Binding( + get: { viewModel.premiumManager.isDebugPremiumToggleEnabled }, + set: { viewModel.premiumManager.isDebugPremiumToggleEnabled = $0 } + ) + ) + .tint(Color.Status.warning) // Icon Generator NavigationLink { IconGeneratorView(config: .selfieCam, appName: "SelfieCam") diff --git a/SelfieCam/Shared/Premium/PremiumManager.swift b/SelfieCam/Shared/Premium/PremiumManager.swift index dd54124..98013ca 100644 --- a/SelfieCam/Shared/Premium/PremiumManager.swift +++ b/SelfieCam/Shared/Premium/PremiumManager.swift @@ -25,16 +25,25 @@ final class PremiumManager: PremiumManaging { } // MARK: - Debug Override - - /// Check if debug premium is enabled via environment variable. - /// Set "ENABLE_DEBUG_PREMIUM" = "1" in your scheme's environment variables to unlock all premium features during debugging. + + /// Debug premium toggle stored in UserDefaults (only available in DEBUG builds) + @AppStorage("debugPremiumEnabled") private var debugPremiumEnabled = false + + /// Check if debug premium is enabled via UserDefaults toggle or environment variable. + /// The toggle in Settings > Debug takes precedence over environment variables. private var isDebugPremiumEnabled: Bool { #if DEBUG - return ProcessInfo.processInfo.environment["ENABLE_DEBUG_PREMIUM"] == "1" + return debugPremiumEnabled || ProcessInfo.processInfo.environment["ENABLE_DEBUG_PREMIUM"] == "1" #else return false #endif } + + /// Public getter/setter for debug premium toggle (DEBUG builds only) + var isDebugPremiumToggleEnabled: Bool { + get { debugPremiumEnabled } + set { debugPremiumEnabled = newValue } + } var isPremium: Bool { // Debug override takes precedence