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
This commit is contained in:
Matt Bruce 2026-01-04 14:43:53 -06:00
parent 1999f7c137
commit 815b91f6ca
5 changed files with 555 additions and 91 deletions

163
AGENTS.md
View File

@ -497,3 +497,166 @@ Color.Primary.background
- If installed, make sure SwiftLint returns no warnings or errors before committing. - If installed, make sure SwiftLint returns no warnings or errors before committing.
- Verify that documentation reflects any new functionality or behavioral changes. - 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<SyncedSettings>` 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.

View File

@ -1,68 +1,272 @@
# AI_Implementation.md # AI Implementation Guide
## How This App Was Architected & Built ## 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 - **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 - **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) - **Bedrock Design System**: Centralized design tokens, no magic numbers
- **No magic numbers**: All dimensions, opacities, durations from centralized `Design` constants
- **Full accessibility**: Dynamic Type, VoiceOver labels/hints/traits/announcements - **Full accessibility**: Dynamic Type, VoiceOver labels/hints/traits/announcements
- **Modern Swift & SwiftUI**: Swift 6 concurrency, `@MainActor`, `foregroundStyle`, `clipShape(.rect)`, `NavigationStack` - **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/ Shared/
├── DesignConstants.swift → Semantic design tokens (spacing, radii, sizes, etc.) ├── DesignConstants.swift → Uses Bedrock design tokens
├── Color+Extensions.swift → Ring light color presets ├── 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/ ├── Protocols/
│ ├── RingLightConfigurable.swift → Border, color, brightness, mirror, smoothing │ ├── RingLightConfigurable.swift → Border, color, brightness
│ ├── CaptureControlling.swift → Timer, grid, zoom, capture mode │ ├── CaptureControlling.swift → Timer, grid, zoom, capture
│ └── PremiumManaging.swift → Subscription state & purchase handling │ └── PremiumManaging.swift → Subscription state
└── Premium/ ├── Premium/
└── PremiumManager.swift → Native StoreKit 2 implementation │ └── PremiumManager.swift → RevenueCat integration
├── Services/
│ └── PhotoLibraryService.swift → Photo saving service
└── Storage/
└── SyncedSettings.swift → iCloud-synced settings
Features/ Features/
├── Camera/ → Main UI, preview, capture logic ├── Camera/ → Main camera UI
├── Settings/ → Configuration screens │ ├── ContentView.swift → Screen coordinator
└── Paywall/ → Pro subscription flow │ ├── 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** ### 1. Ring Light Effect
- Achieved by coloring the safe area background and leaving a centered rectangular window for camera preview - Achieved using `RingLightOverlay` view that creates a colored border around the camera preview
- Border width controlled via user setting - Border width controlled via user setting (10-120pt range)
- Gradient support added for directional "portrait lighting" - Multiple preset colors with premium custom color picker
- Adjustable opacity/brightness (10%-100%)
- Enabled/disabled toggle for quick access
2. **Camera System** ### 2. Camera System
- `AVCaptureSession` with front camera default - Uses **MijickCamera** framework for SwiftUI-native camera handling
- `UIViewRepresentable` wrapper for preview with pinch-to-zoom - Supports front and back camera switching
- Video data output delegate for future real-time filters (skin smoothing placeholder) - 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** ### 3. Capture Enhancements
- Timer with async countdown and accessibility announcements - Self-timer with countdown (3s free, 5s/10s premium)
- Volume button observation via KVO on `AVAudioSession.outputVolume` - Post-capture preview with share functionality
- Flash burst: temporarily sets brightness to 1.0 on capture - Auto-save option to Photo Library
- Front flash using screen brightness
- Support for photo, video, and boomerang modes
4. **Freemium Model** ### 4. Freemium Model
- Built with pure StoreKit 2 (no RevenueCat) - Built with **RevenueCat** for subscription management
- `PremiumManaging` protocol enables easy testing/mocking - `PremiumManager` wraps RevenueCat SDK
- Clean paywall with benefit list and native purchase flow - `PremiumGate` utility for clean premium feature access
- Settings automatically fall back to free defaults when not premium
5. **Reusability Focus** ### 5. iCloud Sync
- All shared logic extracted to protocols - Uses **Bedrock's CloudSyncManager** for settings synchronization
- Ready for future extraction into SPM packages: - `SyncedSettings` model contains all user preferences
- `SelfieCameraKit` - Debounced saves for slider values (300ms delay)
- `SelfieRingLightKit` - Real-time sync status display in Settings
- `SelfiePremiumKit` - Available to all users (not a premium feature)
### Development Process ### 6. Branding System
- Iterative feature additions guided by competitive analysis of top App Store selfie apps - Uses **Bedrock's Branding** module for launch screen and app icon
- Each new capability (timer, boomerang, gradient, subscriptions) added with protocol-first design - `BrandingConfig.swift` defines app-specific colors and symbols
- Strict adherence to no magic numbers, full accessibility, and clean separation - `LaunchBackground.colorset` matches launch screen primary color
- Final structure optimized for maintainability and future library extraction - 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. ---
## 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.

158
README.md
View File

@ -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 ## Features
### Core Camera & Lighting ### Core Camera & Lighting
- Full-screen front-camera preview with true mirror option - Full-screen camera preview with front/back camera switching
- Configurable **screen-based ring light** with adjustable border thickness - Configurable **screen-based ring light** with adjustable border thickness (10-120pt)
- Multiple color temperature presets (Pure White, Warm Cream, Ice Blue, Rose Pink, etc.) - Multiple color temperature presets (Pure White, Warm Cream, Ice Blue, Soft Pink, Warm Amber, Cool Lavender)
- **Directional gradient lighting** for flattering portrait effects - **Ring light brightness control** with adjustable opacity
- Real-time screen brightness control (overrides system brightness while in use) - **Flash modes**: Off, On, Auto
- Flash burst on capture for extra fill light - **Front Flash**: Uses screen brightness for front camera flash effect
- Real-time camera preview with smooth performance
### Capture Modes ### Capture Modes
- Photo capture (saved to Photo Library) - **Photo capture** with high-quality output
- Video recording - **Video recording** (Premium)
- **Boomerang** mode (3-second looping short video) - **Boomerang mode** for looping short videos (Premium)
- 3-second and 10-second self-timer with countdown overlay and VoiceOver announcements - Self-timer with 3-second (free), 5-second, and 10-second (Premium) options
- Pinch-to-zoom gesture - Pinch-to-zoom gesture support
- Volume button shutter support (photo or video start/stop)
- Rule-of-thirds grid overlay (toggleable) - Rule-of-thirds grid overlay (toggleable)
- Post-capture preview with share functionality
### Premium Features (Freemium Model) ### Premium Features (Freemium Model)
- All advanced color presets + custom colors - **Custom ring light colors** with full color picker
- Gradient and directional lighting - **Premium color presets**: Ice Blue, Soft Pink, Warm Amber, Cool Lavender
- Advanced beauty filters (coming soon) - **Flash Sync**: Match flash color with ring light color
- Unlimited boomerang length - **HDR Mode**: High Dynamic Range photo capture
- No watermarks - **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 - 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 ### Accessibility & Polish
- Full VoiceOver support with meaningful labels, hints, and announcements - 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`) - String Catalog localization ready (`.xcstrings`)
- Prevents screen dimming during use - Consistent design system using Bedrock framework
- Restores original brightness on background/app close - Prevents screen dimming during camera use
## Screenshots ## Screenshots
*(Add App Store-ready screenshots here once built)* *(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+ - Xcode 16+
- Swift 6 language mode - 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 ## Setup
### 1. Clone the Repository ### 1. Clone the Repository
```bash ```bash
git clone https://github.com/yourusername/SelfieRingLight.git git clone https://github.com/yourusername/SelfieCam.git
cd SelfieRingLight cd SelfieCam
``` ```
### 2. Configure API Keys ### 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: 1. Copy the template file:
```bash ```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: 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. 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: 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 - Camera access required for preview and capture
- Photo Library access required to save photos/videos - Photo Library access required to save photos/videos
- Microphone access required for video recording - Microphone access required for video recording
- iCloud access for settings synchronization (optional)
- No data collection, no analytics, no tracking - No data collection, no analytics, no tracking
## Monetization ## Monetization
Freemium model with optional "Pro" subscription: Freemium model with optional "Pro" subscription:
- Free: Basic ring light, standard colors, photo/video, timer, zoom - **Free**: Basic ring light, standard colors (Pure White, Warm Cream), photo capture, 3s timer, grid, zoom
- Pro: Full color palette, gradients, advanced features, future updates - **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. Implemented with RevenueCat for reliable subscription management.
## Project Structure ## Project Structure
``` ```
SelfieRingLight/ SelfieCam/
├── App/ # App entry point ├── App/ # App entry point with launch screen
├── Configuration/ # xcconfig files (API keys)
├── Features/ ├── Features/
│ ├── Camera/ # Camera preview, capture, view model │ ├── Camera/ # Main camera UI
│ ├── Paywall/ # Pro subscription flow │ │ ├── ContentView.swift # Main screen coordinator
│ └── Settings/ # Configuration screens │ │ ├── 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/ ├── Shared/
│ ├── Configuration/ # xcconfig files (API keys) │ ├── BrandingConfig.swift # App icon & launch screen config
│ ├── Premium/ # PremiumManager (RevenueCat) │ ├── DesignConstants.swift # Design tokens (uses Bedrock)
│ ├── Protocols/ # Shared protocols │ ├── Color+Extensions.swift # Ring light color presets
│ ├── Color+Extensions.swift # Ring light color presets │ ├── Models/ # Data models
│ └── DesignConstants.swift # Design tokens │ │ ├── CameraFlashMode.swift
└── Resources/ # Assets, localization │ │ ├── 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 ## License
*(Add your license here)* *(Add your license here)*

View File

@ -762,10 +762,20 @@ struct SettingsView: View {
} }
// MARK: - Branding Debug Section // MARK: - Branding Debug Section
#if DEBUG #if DEBUG
private var brandingDebugSection: some View { private var brandingDebugSection: some View {
VStack(spacing: Design.Spacing.small) { 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 // Icon Generator
NavigationLink { NavigationLink {
IconGeneratorView(config: .selfieCam, appName: "SelfieCam") IconGeneratorView(config: .selfieCam, appName: "SelfieCam")

View File

@ -25,16 +25,25 @@ final class PremiumManager: PremiumManaging {
} }
// MARK: - Debug Override // MARK: - Debug Override
/// Check if debug premium is enabled via environment variable. /// Debug premium toggle stored in UserDefaults (only available in DEBUG builds)
/// Set "ENABLE_DEBUG_PREMIUM" = "1" in your scheme's environment variables to unlock all premium features during debugging. @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 { private var isDebugPremiumEnabled: Bool {
#if DEBUG #if DEBUG
return ProcessInfo.processInfo.environment["ENABLE_DEBUG_PREMIUM"] == "1" return debugPremiumEnabled || ProcessInfo.processInfo.environment["ENABLE_DEBUG_PREMIUM"] == "1"
#else #else
return false return false
#endif #endif
} }
/// Public getter/setter for debug premium toggle (DEBUG builds only)
var isDebugPremiumToggleEnabled: Bool {
get { debugPremiumEnabled }
set { debugPremiumEnabled = newValue }
}
var isPremium: Bool { var isPremium: Bool {
// Debug override takes precedence // Debug override takes precedence