804 lines
45 KiB
Markdown
804 lines
45 KiB
Markdown
# TheNoiseClock - Product Requirements Document
|
|
|
|
## Overview
|
|
TheNoiseClock is a SwiftUI-based iOS application that combines a customizable digital clock display with white noise playback and alarm functionality. The app is designed with a dark theme and focuses on providing a clean, distraction-free interface for time display and ambient sound management.
|
|
|
|
## Core Features
|
|
|
|
### 1. Digital Clock Display
|
|
- **Real-time clock** with automatic updates every second
|
|
- **Customizable time format**: 12-hour or 24-hour display
|
|
- **Optional seconds display** with toggle control
|
|
- **AM/PM badge** for 12-hour format (optional)
|
|
- **Segmented time display** with colon separators that adapt to orientation
|
|
- **Dynamic scaling** that maximizes available screen space usage
|
|
- **Portrait and landscape orientation support** with responsive font sizing
|
|
- **Optimal font sizing** that uses all available space efficiently
|
|
- **Immediate updates** on orientation changes and tab bar visibility changes
|
|
- **Fixed-width digit rendering** to prevent layout shifts and jumping
|
|
- **Individual digit views** with consistent spacing and alignment
|
|
- **Font customization** with family, weight, and design selection
|
|
- **Dynamic dot sizing** that matches selected font weight
|
|
- **Safe area handling** with proper Dynamic Island avoidance on iPhone and full-width layout on iPad
|
|
- **Full-screen mode** with status bar hiding and tab bar expansion
|
|
- **Orientation-aware spacing** for optimal layout in all orientations
|
|
- **Modern iOS 18+ Animations**:
|
|
- **Selectable Animation Styles**: Choose from effective animation styles including None, Spring, Bounce, and Glitch.
|
|
- **Numeric Text Transitions**: Smooth scrolling transitions for digits using `.contentTransition(.numericText())` (available in most styles).
|
|
- **Phase-Based Digit Animations**: Dynamic scale, vertical offset, and jitter effects when digits change.
|
|
- **Glitch Effect**: High-energy digital jitter with random offsets and rapid opacity shifts.
|
|
- **Dynamic Glow Pulsing**: Glow intensity and blur radius pulse during digit transitions for enhanced visual feedback.
|
|
- **Breathing Colon Effect**: Subtle opacity pulsing for colon separators to add life to the display.
|
|
|
|
### 2. Clock Customization
|
|
- **Selectable digit animation styles**: Choose from None, Spring, Bounce, and Glitch
|
|
- **Color customization**: User-selectable digit colors with color picker
|
|
- **Background color**: Customizable background with color picker
|
|
- **Glow effects**: Adjustable glow intensity (0-100%)
|
|
- **Size control**: Manual scaling (0-100%) or auto-fit mode
|
|
- **Opacity controls**: Separate opacity for clock digits and overlays
|
|
- **Random color mode**: Automatically changes digit color every minute
|
|
- **Preset themes**: Quick "Night" (black/white) and "Day" (white/black) themes
|
|
- **Font family selection**: Choose from System, Helvetica, Arial, Times New Roman, Georgia, Verdana, Monaco, Courier fonts
|
|
- **Font weight options**: Ultra Light, Thin, Light, Regular, Medium, Semibold, Bold, Heavy, Black
|
|
- **Font design choices**: Default, Serif, Rounded, Monospaced designs
|
|
- **Live font preview**: Real-time preview of font changes in settings
|
|
- **Font persistence**: All font settings saved and restored automatically
|
|
|
|
### 3. Display Modes
|
|
- **Normal mode**: Standard interface with navigation and settings
|
|
- **Display mode**: Full-screen clock activated by long-press (0.6 seconds)
|
|
- **Automatic UI hiding**: Tab bar and navigation elements hide in display mode
|
|
- **iPad compatibility**: Uses SwiftUI's native `.toolbar(.hidden, for: .tabBar)` for proper iPad sidebar-style tab bar hiding
|
|
- **Cross-platform support**: Works correctly on both iPhone (bottom tab bar) and iPad (top sidebar tab bar)
|
|
- **Smooth transitions**: Animated transitions between modes
|
|
- **Status bar control**: Status bar hidden on the Clock tab (including full-screen mode)
|
|
- **Safe area expansion**: Clock expands into tab bar area when hidden
|
|
- **Dynamic Island awareness**: Proper spacing to avoid Dynamic Island overlap
|
|
- **Orientation handling**: Full-screen mode works in both portrait and landscape
|
|
- **Keep awake functionality**: Optional screen wake lock to prevent device sleep in display mode
|
|
- **Battery optimization**: Wake lock automatically disabled when exiting display mode
|
|
|
|
### 4. Information Overlays
|
|
- **Battery level display**: Real-time battery percentage with dynamic icon
|
|
- **Battery state awareness**: Shows charging state with lightning bolt icon
|
|
- **Battery color coding**: Green (50-100%), Yellow (20-49%), Orange (10-19%), Red (<10%)
|
|
- **Charging indicator**: Green lightning bolt icon when device is charging
|
|
- **Date display**: Current date in "d MMMM EEE" format (e.g., "7 September Mon")
|
|
- **Overlay opacity control**: Independent opacity for battery/date overlays
|
|
- **Automatic updates**: Battery and date update in real-time
|
|
- **Battery service integration**: Dedicated BatteryService for monitoring and state management
|
|
|
|
### 5. White Noise Player
|
|
- **Multiple sound options**:
|
|
- White Noise (`white-noise.mp3`)
|
|
- Heavy Rain White Noise (`heavy-rain-white-noise.mp3`)
|
|
- Fan White Noise (`fan-white-noise-heater.mp3`)
|
|
- **Continuous playback**: Sounds loop indefinitely
|
|
- **Advanced sound selection**: Category-based grid with search and preview
|
|
- **Simple controls**: Play/Stop button with visual feedback
|
|
- **Auto-stop on selection**: Automatically stops current sound when selecting new one
|
|
- **Sound preview**: 3-second preview on long-press
|
|
- **JSON-based configuration**: Sound definitions loaded from external configuration
|
|
- **Bundle organization**: Sounds organized in category-based bundles
|
|
- **Shared audio player**: Singleton pattern prevents audio conflicts
|
|
- **Background audio support**: Continues playing when app is backgrounded
|
|
- **Audio interruption handling**: Automatically resumes after phone calls or route changes
|
|
- **Wake lock integration**: Prevents device sleep while audio is playing
|
|
- **Bluetooth audio support**: Works with AirPods and other Bluetooth audio devices
|
|
- **Responsive layout**: Optimized for both portrait and landscape orientations
|
|
- **AudioPlaybackKit integration**: Powered by reusable Swift package for audio functionality
|
|
|
|
### 6. Advanced Alarm System
|
|
- **Multiple alarms**: Create and manage unlimited alarms
|
|
- **Rich alarm editor**: Full-featured alarm creation and editing interface
|
|
- **Time selection**: Wheel-style date picker with optimized font sizing for maximum readability
|
|
- **Dynamic alarm sounds**: Configurable alarm sounds loaded from dedicated alarm-sounds.json configuration
|
|
- **Sound preview**: Play/stop functionality for testing alarm sounds before selection
|
|
- **Sound organization**: Alarm sounds organized in dedicated AlarmSounds.bundle with categories
|
|
- **Custom labels**: User-defined alarm names and descriptions
|
|
- **Repeat schedules**: Set alarms to repeat on specific weekdays or daily
|
|
- **Sound selection**: Choose from extensive alarm sounds with live preview
|
|
- **Volume control**: Adjustable alarm volume (0-100%)
|
|
- **Vibration settings**: Enable/disable vibration for each alarm
|
|
- **Snooze functionality**: Configurable snooze duration (5, 7, 8, 9, 10, 15, 20 minutes)
|
|
- **Smart notifications**: Automatic scheduling for one-time and repeating alarms
|
|
- **Enable/disable toggles**: Individual alarm control with instant feedback
|
|
- **Notification integration**: Uses iOS UserNotifications framework with proper scheduling
|
|
- **Background limitations**: Full alarm sound and screen require the app to be foregrounded; background alarms use notification sound
|
|
- **Keep Awake prompt**: In-app popup enables Keep Awake without digging into settings
|
|
- **Keep Awake guidance**: Banner messaging explains why Keep Awake improves alarm reliability
|
|
- **Persistent storage**: Alarms saved to UserDefaults with backward compatibility
|
|
- **Alarm management**: Add, edit, delete, and duplicate alarms
|
|
- **Next trigger preview**: Shows when the next alarm will fire
|
|
- **Responsive time picker**: Font sizes adapt to available space and orientation
|
|
- **AlarmSoundService integration**: Dedicated service for alarm-specific sound management
|
|
- **In-app alarm screen**: Full-screen alarm UI with Snooze/Stop when the app is active
|
|
- **Foreground alarm sound**: In-app playback of the selected alarm sound and volume
|
|
- **Notification tap routing**: Tapping an alarm notification opens the alarm screen
|
|
- **Foreground handling**: Alarm notifications surface as in-app UI instead of banners
|
|
|
|
## Advanced Clock Display Features
|
|
|
|
### Fixed-Width Digit Rendering
|
|
- **Individual digit views**: Each digit (0-9) rendered in its own view component
|
|
- **Consistent spacing**: All digits use the width of the widest digit ("8") for uniform layout
|
|
- **Height consistency**: All digits use the height of the tallest digit ("8") to prevent vertical jumping
|
|
- **Layout stability**: No shifting or jumping when time changes (e.g., "11" to "12")
|
|
- **Perfect centering**: Each digit is centered within its fixed-width container
|
|
|
|
### Advanced Font Customization System
|
|
- **Type-safe font selection**: FontFamily enum with System, Helvetica, Arial, Times New Roman, Georgia, Verdana, Courier, Futura, Avenir, Roboto options
|
|
- **Weight variations**: Font.Weight enum with 9 weight options from Ultra Light to Black
|
|
- **Design choices**: Font.Design enum with Default, Serif, Rounded, Monospaced designs
|
|
- **Live preview**: Real-time font preview in settings interface with allCases picker integration
|
|
- **Binary search font sizing**: Advanced calculateOptimalFontSize with tight bounding box calculations
|
|
- **Dynamic font sizing**: Real-time font size optimization based on container geometry
|
|
- **UIFont integration**: Proper font measurement with createUIFont and tightBoundingBox utilities
|
|
- **Weight-based dot scaling**: Colon dots automatically scale with font weight using dotSizeMultiplier
|
|
- **Enum-based architecture**: Type-safe font selection eliminates string-based errors
|
|
- **Legacy compatibility**: Backward compatibility methods for existing code integration
|
|
|
|
### Dynamic Layout and Sizing
|
|
- **GeometryReader integration**: Real-time container size detection
|
|
- **Orientation-aware calculations**: Different sizing algorithms for portrait vs landscape
|
|
- **Safe area handling**: Proper Dynamic Island avoidance and tab bar expansion
|
|
- **Maximum space utilization**: Font sizes calculated to use all available space
|
|
- **Responsive updates**: Immediate recalculation on orientation or layout changes
|
|
|
|
### Advanced Spacing and Alignment
|
|
- **Unified colon component**: Single ColonView with isHorizontal parameter for both orientations
|
|
- **Orientation-aware spacing**: Different spacing values for portrait vs landscape
|
|
- **Consistent segment spacing**: Uniform spacing between hours, minutes, seconds
|
|
- **Dot weight matching**: Colon dots scale with selected font weight
|
|
- **Dot sizing balance**: Tuned dot sizing multipliers preserve readability while maximizing digit size in tight layouts
|
|
- **Overflow prevention**: Spacing calculations prevent content clipping
|
|
- **Perfect centering**: All elements centered both horizontally and vertically
|
|
- **Component consolidation**: Eliminated redundant HorizontalColon and VerticalColon views
|
|
|
|
### Full-Screen Mode Enhancements
|
|
- **Status bar hiding**: Status bar remains hidden while on the Clock tab
|
|
- **Tab bar expansion**: Clock expands into tab bar area when hidden
|
|
- **Safe area management**: Proper handling of Dynamic Island and other safe areas
|
|
- **Smooth transitions**: Animated transitions between normal and full-screen modes
|
|
- **Orientation support**: Full-screen mode works seamlessly in all orientations
|
|
|
|
## Technical Architecture
|
|
|
|
### Swift Package Architecture
|
|
|
|
TheNoiseClock has been refactored to use a modular Swift Package architecture for improved code reusability and maintainability:
|
|
|
|
#### AudioPlaybackKit Package
|
|
- **Purpose**: Reusable audio playback functionality for iOS and tvOS applications
|
|
- **Platform Support**: iOS 17.0+ and tvOS 17.0+
|
|
- **Core Components**:
|
|
- `Sound` model: Generic sound data structure with Codable support and GUID generation
|
|
- `SoundConfiguration` models: Configuration structures for sound management
|
|
- `SoundConfigurationService`: Generic sound configuration service with JSON loading
|
|
- `NoisePlayer`: Audio playback service with background support
|
|
- `WakeLockService`: Screen wake lock management
|
|
- `NoiseViewModel`: Audio playback state management
|
|
- `AudioConstants`: Audio-related constants and configuration
|
|
- **Key Features**:
|
|
- Generic sound management (no alarm-specific functionality)
|
|
- Fatal error handling for missing configuration files
|
|
- Platform-conditional compilation for tvOS compatibility
|
|
- Modern @Observable state management
|
|
- Background audio support with interruption handling
|
|
|
|
#### Package Integration
|
|
- **Local Package**: AudioPlaybackKit is included as a local Swift package dependency
|
|
- **Xcode Integration**: Properly configured in project.pbxproj with XCLocalSwiftPackageReference
|
|
- **Import Usage**: Main app imports AudioPlaybackKit for audio functionality
|
|
- **Separation of Concerns**: Generic audio functionality in package, app-specific logic in main app
|
|
|
|
#### App-Specific Extensions
|
|
- **AlarmSoundService**: Dedicated service in main app for alarm-specific sound management
|
|
- **Configuration Separation**: Alarm sounds use separate alarm-sounds.json file
|
|
- **Category Constants**: Hardcoded alarm category ID to avoid magic strings
|
|
- **Service Pattern**: Extension pattern for app-specific functionality
|
|
|
|
### Code Organization Principles
|
|
|
|
**TOP PRIORITY:** The codebase must be built with the following architectural principles from the beginning:
|
|
|
|
- **True Separation of Concerns:**
|
|
- Many small files with focused responsibilities
|
|
- Each module/class should have a single, well-defined purpose
|
|
- Avoid monolithic files with mixed responsibilities
|
|
|
|
- **View Structure Requirements:**
|
|
- **Single View Per File:** Each SwiftUI view must be in its own file
|
|
- **No Nested Views:** Views should not contain other view structs/classes in the same file
|
|
- **Component Extraction:** Complex views must be broken down into smaller, reusable components
|
|
- **Clean Main Views:** Main view files should only contain the primary view logic and helper methods
|
|
- **Component Organization:** Supporting views should be placed in appropriate `Components/` subdirectories
|
|
|
|
- **Constants and Enums:**
|
|
- Create constants, enums, and configuration objects to avoid duplicate code or values
|
|
- Centralize magic numbers, strings, and configuration values
|
|
- Use enums for type safety and clarity
|
|
|
|
- **Readability and Maintainability:**
|
|
- Code should be self-documenting with clear naming conventions
|
|
- Easy to understand, extend, and refactor
|
|
- Consistent patterns throughout the codebase
|
|
|
|
- **Extensibility:**
|
|
- Design for future growth and feature additions
|
|
- Modular architecture that allows easy integration of new components
|
|
- Clear interfaces between modules
|
|
|
|
- **Refactorability:**
|
|
- Code structure should make future refactoring straightforward
|
|
- Minimize coupling between components
|
|
- Use dependency injection and abstraction where appropriate
|
|
|
|
These principles are fundamental to the project's long-term success and must be applied consistently throughout development.
|
|
|
|
### App Structure
|
|
- **Main App**: `TheNoiseClockApp.swift` - Entry point with WindowGroup
|
|
- **Branded launch**: AppLaunchView wrapped in a Color.Branding.primary ZStack
|
|
- **Tab-based navigation**: Three main tabs (Clock, Alarms, Noise)
|
|
- **SwiftUI framework**: Modern declarative UI framework with iOS 18+ and iOS 26 features
|
|
- **Dark theme**: Preferred color scheme set to dark
|
|
|
|
### Data Models
|
|
- **ClockStyle**: @Observable class for clock customization settings
|
|
- Time format preferences (24-hour, seconds, AM/PM)
|
|
- Visual settings (colors, glow, scale, opacity)
|
|
- Overlay settings (battery, date, opacity)
|
|
- Background settings
|
|
- Type-safe font customization (FontFamily, Font.Weight, Font.Design enums)
|
|
- Color caching for performance optimization
|
|
- Persistent storage with JSON encoding/decoding and enum-to-string conversion
|
|
- Backward compatibility for legacy string-based font settings
|
|
- **Alarm**: Codable struct for comprehensive alarm data
|
|
- UUID identifier
|
|
- Time and enabled state
|
|
- Custom label and description
|
|
- Repeat schedule (weekdays)
|
|
- Sound name with volume control
|
|
- Vibration settings
|
|
- Snooze duration configuration
|
|
- **Sound** (AudioPlaybackKit): Generic sound data model with Codable support
|
|
- Unique GUID identifier (auto-generated)
|
|
- Display name and file name
|
|
- Category and description
|
|
- Optional bundle name for organization
|
|
- Optional isDefault flag for default sound selection
|
|
- Custom Codable implementation with GUID generation
|
|
- **SoundConfiguration** (AudioPlaybackKit): Configuration structure for sound management
|
|
- Array of Sound objects
|
|
- Sound categories and audio settings
|
|
- JSON-based configuration loading
|
|
- **LegacyAlarm**: Backward compatibility struct for old alarm data
|
|
|
|
### Data Persistence
|
|
- **AppStorage**: ClockStyle settings persisted as JSON
|
|
- **UserDefaults**: Alarm data persisted as JSON
|
|
- **Bundle resources**: Audio files stored in app bundle
|
|
|
|
### Audio System
|
|
- **AudioPlaybackKit Package**: Reusable audio functionality in Swift package
|
|
- **AVFoundation**: AVAudioPlayer for noise playback
|
|
- **@Observable NoisePlayer**: Modern state management with preloading
|
|
- **Looping playback**: Infinite loop for ambient sounds
|
|
- **Audio session management**: Proper audio session configuration with background support
|
|
- **Error handling**: Fatal error handling for missing configuration files
|
|
- **AlarmTonePlayer**: Dedicated player for alarm sound previews
|
|
- **Background audio**: Continues playback when app is backgrounded
|
|
- **Interruption handling**: Automatic resume after phone calls and route changes
|
|
- **Wake lock integration**: Prevents device sleep during audio playback
|
|
- **Focus mode awareness**: Monitors and respects Focus mode settings
|
|
- **Notification compatibility**: Ensures alarms work with Focus modes enabled
|
|
- **Configuration separation**: Separate JSON files for ambient sounds (sounds.json) and alarm sounds (alarm-sounds.json)
|
|
- **Generic sound management**: AudioPlaybackKit provides generic sound functionality
|
|
- **App-specific extensions**: AlarmSoundService handles alarm-specific sound management
|
|
|
|
### Battery System
|
|
- **@Observable BatteryService**: Modern state management for battery monitoring
|
|
- **Real-time monitoring**: Continuous battery level and charging state tracking
|
|
- **UIDevice integration**: Native iOS battery monitoring with proper lifecycle management
|
|
- **Charging state detection**: Automatic detection of charging/not charging states
|
|
- **Color-coded display**: Dynamic color coding based on battery level (green/yellow/orange/red)
|
|
- **Icon management**: Dynamic battery icons with charging state indicators
|
|
- **Lifecycle management**: Automatic start/stop monitoring based on view visibility
|
|
- **Pure view architecture**: BatteryOverlayView is purely presentational with no business logic
|
|
|
|
### Notification System
|
|
- **UserNotifications**: iOS notification framework
|
|
- **Permission handling**: Automatic permission requests
|
|
- **Smart scheduling**: One-time and repeating alarm support
|
|
- **Calendar triggers**: Precise alarm scheduling with weekday support
|
|
- **Sound customization**: System sound selection with volume control
|
|
- **Multiple notifications**: Support for repeating alarms with unique identifiers
|
|
|
|
### Wake Lock System
|
|
- **WakeLockService**: Singleton service for managing screen wake lock
|
|
- **Display mode integration**: Automatically enables wake lock in full-screen display mode
|
|
- **Audio integration**: Enables wake lock during audio playback to prevent device sleep
|
|
- **Battery optimization**: Automatic wake lock management with proper cleanup
|
|
- **Timer-based maintenance**: Periodic wake lock refresh to ensure continuous operation
|
|
- **State management**: Tracks wake lock status and provides toggle functionality
|
|
|
|
### Focus Mode Integration
|
|
- **FocusModeService**: Comprehensive service for handling Focus mode interactions
|
|
- **Notification compatibility**: Ensures alarms work properly with Focus modes
|
|
- **Audio awareness**: Monitors Focus mode status for audio playback decisions
|
|
- **Permission management**: Requests notification permissions compatible with Focus modes
|
|
- **Alarm scheduling**: Uses Focus mode-aware notification scheduling
|
|
- **User settings**: Toggle to respect or override Focus mode restrictions
|
|
- **Guidance system**: Provides user instructions for optimal Focus mode configuration
|
|
|
|
## User Interface Design
|
|
|
|
### Navigation
|
|
- **TabView**: Three-tab interface (Clock, Alarms, Noise)
|
|
- **NavigationStack**: Modern navigation with back button support
|
|
- **Navigation destinations**: Deep linking for alarm editing
|
|
- **Toolbar integration**: Settings and add buttons in navigation bars
|
|
- **Sheet presentations**: Modal settings and alarm creation
|
|
- **Title presentation**: Inline titles on iPhone; titles hidden on iPad tab screens
|
|
|
|
### Visual Design
|
|
- **Rounded corners**: Modern iOS design language
|
|
- **Modern animations**: iOS 18+ smooth and bouncy animations
|
|
- **Color consistency**: Bedrock theme with branded surfaces and accents
|
|
- **Branded launch**: AppLaunchView with matching launch screen background
|
|
- **Accessibility**: Proper labels and hidden decorative elements
|
|
- **Card-based layouts**: Bedrock settings cards for grouping controls
|
|
- **Interactive controls**: Bedrock toggles, sliders, pickers, and color pickers
|
|
|
|
### Settings Interface
|
|
- **Bedrock layout**: Section headers with card-based grouping
|
|
- **Interactive controls**: SettingsToggle, SettingsSlider, menu pickers, color pickers
|
|
- **Type-safe font selection**: FontFamily.allCases, Font.Weight.allCases, Font.Design.allCases pickers
|
|
- **Real-time updates**: Changes apply immediately with live preview
|
|
- **Sheet presentation**: Full-screen settings sheet for uninterrupted editing
|
|
- **Enum-based architecture**: Type-safe picker selections eliminate string-based errors
|
|
- **Always-visible settings**: Advanced sections are always shown for clarity
|
|
|
|
## File Structure and Organization
|
|
|
|
### Recommended File Organization
|
|
Following the separation of concerns principle, the codebase is organized into focused, single-responsibility files with Swift Package integration:
|
|
|
|
```
|
|
TheNoiseClock/
|
|
├── README.md # App Store copy + project overview
|
|
├── AudioPlaybackKit/ # Swift Package for reusable audio functionality
|
|
│ ├── Package.swift # Package configuration (iOS 17.0+, tvOS 17.0+)
|
|
│ └── Sources/AudioPlaybackKit/
|
|
│ ├── Models/
|
|
│ │ ├── Sound.swift # Generic sound data model with Codable support
|
|
│ │ └── SoundConfiguration.swift # Sound configuration models and service
|
|
│ ├── Services/
|
|
│ │ ├── NoisePlayer.swift # Audio playback service
|
|
│ │ └── WakeLockService.swift # Screen wake lock management
|
|
│ ├── ViewModels/
|
|
│ │ └── NoiseViewModel.swift # Audio playback state management
|
|
│ └── Constants/
|
|
│ └── AudioConstants.swift # Audio-related constants
|
|
├── TheNoiseClock/ # Main application
|
|
│ ├── App/
|
|
│ │ ├── TheNoiseClockApp.swift # App entry point and configuration
|
|
│ │ └── ContentView.swift # Main tab navigation coordinator
|
|
│ ├── Configuration/
|
|
│ │ ├── AppIdentifiers.swift # xcconfig-backed identifiers
|
|
│ │ ├── Base.xcconfig # Company/app identifiers
|
|
│ │ ├── Debug.xcconfig # Debug settings
|
|
│ │ └── Release.xcconfig # Release settings
|
|
│ ├── Shared/
|
|
│ │ ├── Design/
|
|
│ │ │ ├── BrandingConfig.swift # Bedrock branding + launch config
|
|
│ │ │ ├── AppConstants.swift # App-wide constants and configuration
|
|
│ │ │ ├── NoiseClockTheme.swift # Bedrock app color theme
|
|
│ │ │ ├── Design+NoiseClock.swift # App-specific Design extensions
|
|
│ │ │ └── Fonts/
|
|
│ │ │ ├── Font.Design.swift
|
|
│ │ │ ├── Font.Weight.swift
|
|
│ │ │ ├── FontFamily.swift
|
|
│ │ │ └── FontUtils.swift
|
|
│ │ ├── Extensions/
|
|
│ │ │ ├── Color+Extensions.swift # Color utilities and extensions
|
|
│ │ │ ├── Date+Extensions.swift # Date formatting and utilities
|
|
│ │ │ └── View+Extensions.swift # Common view modifiers and responsive utilities
|
|
│ │ ├── Models/
|
|
│ │ │ └── SoundCategory.swift # Shared sound category definitions
|
|
│ │ └── Utilities/
|
|
│ │ ├── ColorUtils.swift # Color manipulation utilities
|
|
│ │ ├── NotificationUtils.swift # Notification helper functions
|
|
│ │ └── AlarmNotifications.swift # Alarm notification constants and events
|
|
│ ├── Features/
|
|
│ │ ├── Clock/
|
|
│ │ │ ├── Models/
|
|
│ │ │ │ └── ClockStyle.swift
|
|
│ │ │ ├── State/
|
|
│ │ │ │ └── ClockViewModel.swift
|
|
│ │ │ ├── Services/
|
|
│ │ │ │ ├── AmbientLightService.swift
|
|
│ │ │ │ └── BatteryService.swift
|
|
│ │ │ └── Views/
|
|
│ │ │ ├── ClockView.swift
|
|
│ │ │ ├── ClockSettingsView.swift
|
|
│ │ │ └── Components/
|
|
│ │ │ ├── TimeDisplayView.swift
|
|
│ │ │ ├── TimeSegment.swift
|
|
│ │ │ ├── DigitView.swift
|
|
│ │ │ ├── ColonView.swift
|
|
│ │ │ ├── DotCircle.swift
|
|
│ │ │ ├── BatteryOverlayView.swift
|
|
│ │ │ ├── DateOverlayView.swift
|
|
│ │ │ ├── TopOverlayView.swift
|
|
│ │ │ ├── ClockDisplayContainer.swift
|
|
│ │ │ ├── ClockOverlayContainer.swift
|
|
│ │ │ ├── ClockGestureHandler.swift
|
|
│ │ │ ├── ClockToolbar.swift
|
|
│ │ │ ├── FullScreenHintView.swift
|
|
│ │ │ └── Settings/
|
|
│ │ │ ├── BasicAppearanceSection.swift
|
|
│ │ │ ├── BasicDisplaySection.swift
|
|
│ │ │ ├── AdvancedAppearanceSection.swift
|
|
│ │ │ ├── AdvancedDisplaySection.swift
|
|
│ │ │ ├── FontSection.swift
|
|
│ │ │ ├── NightModeSection.swift
|
|
│ │ │ ├── OverlaySection.swift
|
|
│ │ │ └── TimePickerView.swift
|
|
│ │ ├── Alarms/
|
|
│ │ │ ├── Models/
|
|
│ │ │ │ └── Alarm.swift
|
|
│ │ │ ├── State/
|
|
│ │ │ │ └── AlarmViewModel.swift
|
|
│ │ │ ├── Services/
|
|
│ │ │ │ ├── AlarmService.swift
|
|
│ │ │ │ ├── AlarmSoundService.swift
|
|
│ │ │ │ ├── FocusModeService.swift
|
|
│ │ │ │ ├── NotificationService.swift
|
|
│ │ │ │ └── NotificationDelegate.swift
|
|
│ │ │ └── Views/
|
|
│ │ │ ├── AlarmView.swift
|
|
│ │ │ ├── AddAlarmView.swift
|
|
│ │ │ ├── EditAlarmView.swift
|
|
│ │ │ ├── AlarmScreen.swift
|
|
│ │ │ └── Components/
|
|
│ │ │ ├── AlarmRowView.swift
|
|
│ │ │ ├── EmptyAlarmsView.swift
|
|
│ │ │ ├── LabelEditView.swift
|
|
│ │ │ ├── NotificationMessageEditView.swift
|
|
│ │ │ ├── SnoozeSelectionView.swift
|
|
│ │ │ ├── SoundSelectionView.swift
|
|
│ │ │ ├── TimePickerSection.swift
|
|
│ │ │ └── TimeUntilAlarmSection.swift
|
|
│ │ ├── Noise/
|
|
│ │ │ └── Views/
|
|
│ │ │ ├── NoiseView.swift
|
|
│ │ │ └── Components/
|
|
│ │ │ ├── SoundCategoryView.swift
|
|
│ │ │ └── SoundControlView.swift
|
|
│ │ └── Onboarding/
|
|
│ │ └── Views/
|
|
│ │ ├── OnboardingView.swift
|
|
│ │ └── Components/
|
|
│ │ └── OnboardingPageView.swift
|
|
│ └── Resources/
|
|
│ ├── LaunchScreen.storyboard # Branded native launch screen
|
|
│ ├── sounds.json # Ambient sound configuration and definitions
|
|
│ ├── alarm-sounds.json # Alarm sound configuration and definitions
|
|
│ ├── Ambient.bundle/ # Ambient sound category
|
|
│ │ └── white-noise.mp3
|
|
│ ├── Nature.bundle/ # Nature sound category
|
|
│ │ └── heavy-rain-white-noise.mp3
|
|
│ ├── Mechanical.bundle/ # Mechanical sound category
|
|
│ │ └── fan-white-noise-heater.mp3
|
|
│ ├── AlarmSounds.bundle/ # Alarm sound category
|
|
│ │ ├── digital-alarm.caf
|
|
│ │ ├── classic-alarm.caf
|
|
│ │ ├── beep-alarm.caf
|
|
│ │ ├── siren-alarm.caf
|
|
│ │ └── buzzing-alarm.caf
|
|
│ └── Assets.xcassets/
|
|
│ └── [Asset catalogs]
|
|
└── TheNoiseClock.xcodeproj/ # Xcode project with AudioPlaybackKit dependency
|
|
└── project.pbxproj # Project configuration with local package reference
|
|
```
|
|
|
|
### File Naming Conventions
|
|
- **Views**: Use descriptive names ending in `View` (e.g., `ClockView`, `AlarmRowView`)
|
|
- **ViewModels**: End with `ViewModel` (e.g., `ClockViewModel`, `AlarmViewModel`)
|
|
- **Services**: End with `Service` (e.g., `AlarmService`, `NotificationService`)
|
|
- **Models**: Use noun names (e.g., `Alarm`, `Sound`, `ClockStyle`)
|
|
- **Extensions**: Use `Type+Extensions` format (e.g., `Color+Extensions`)
|
|
- **Constants**: Use descriptive names ending in `Constants` (e.g., `AppConstants`)
|
|
|
|
### Code Organization Best Practices
|
|
- **Single Responsibility**: Each file should have one clear purpose
|
|
- **Dependency Injection**: Use protocols and dependency injection for testability
|
|
- **Protocol-Oriented Design**: Define protocols for services and data sources
|
|
- **Error Handling**: Centralized error types and handling patterns
|
|
- **Testing**: Separate test targets with comprehensive coverage
|
|
|
|
### Documentation Maintenance Requirements
|
|
|
|
**CRITICAL:** The PRD must be kept up-to-date with all code changes. The following procedures are mandatory:
|
|
|
|
#### Automatic PRD Updates
|
|
- **Every code change** that affects architecture, features, or file structure **MUST** include a corresponding PRD update
|
|
- **AI Assistant Responsibility**: When making code changes, the AI assistant must automatically:
|
|
1. **Identify PRD sections** that need updating based on the changes made
|
|
2. **Update relevant sections** without being asked
|
|
3. **Add new features** to the appropriate feature sections
|
|
4. **Update file structure** when new files or components are created
|
|
5. **Document new requirements** or architectural decisions
|
|
6. **Maintain consistency** between code and documentation
|
|
|
|
#### PRD Update Triggers
|
|
The following changes **automatically require** PRD updates:
|
|
- **New files or components** → Update file structure section
|
|
- **New features or functionality** → Update core features section
|
|
- **Architectural changes** → Update code organization principles
|
|
- **New services or models** → Update technical architecture
|
|
- **UI/UX changes** → Update user interaction sections
|
|
- **Configuration changes** → Update technical requirements
|
|
- **Bundle or resource changes** → Update resources section
|
|
|
|
#### Documentation Standards
|
|
- **Real-time updates**: PRD updates should happen in the same conversation as code changes
|
|
- **Comprehensive coverage**: All aspects of changes must be documented
|
|
- **Version consistency**: Code and documentation must always be in sync
|
|
- **No manual requests**: Users should not need to ask for PRD updates
|
|
|
|
### 7. Onboarding Experience
|
|
- **First-launch detection**: Uses OnboardingState to detect first-time users
|
|
- **Welcome screen**: Introduces the app with branded visuals
|
|
- **Feature highlights**: Dedicated pages for Clock, Alarms, and Noise features
|
|
- **Permission request**: Notification permission request with contextual explanation
|
|
- **Skip option**: Users can skip onboarding at any time
|
|
- **Persistent state**: Onboarding completion saved to UserDefaults
|
|
- **Smooth transitions**: Animated page transitions with page indicators
|
|
- **Get Started flow**: Clear call-to-action to complete onboarding
|
|
|
|
## Key User Interactions
|
|
|
|
### Clock Tab
|
|
1. **View time**: Real-time clock display
|
|
2. **Access settings**: Tap gear icon in navigation bar
|
|
3. **Enter display mode**: Long-press anywhere on clock (0.6 seconds)
|
|
4. **Exit display mode**: Long-press again to return to normal mode
|
|
|
|
### Settings
|
|
1. **Time format**: Toggle 24-hour, seconds, AM/PM display
|
|
2. **Appearance**: Adjust colors, glow, size, opacity
|
|
3. **Display**: Control keep awake functionality for display mode
|
|
4. **Keep Awake prompt**: Auto-prompt when needed (alarms tab, enabling alarms, display mode)
|
|
5. **Focus Modes**: Control how app behaves with Focus modes (Do Not Disturb)
|
|
6. **Overlays**: Control battery and date display
|
|
7. **Background**: Set background color and use presets
|
|
|
|
### Alarms Tab
|
|
1. **View alarms**: List of all created alarms with labels and repeat schedules
|
|
2. **Add alarm**: Tap + button to create new alarm with full editor
|
|
3. **Edit alarm**: Tap any alarm to open comprehensive editor
|
|
4. **Toggle alarm**: Use switch to enable/disable
|
|
5. **Delete alarm**: Swipe to delete or use delete button in editor
|
|
6. **Alarm editor features**:
|
|
- Time picker with next trigger preview
|
|
- Custom label editing
|
|
- Repeat schedule selection
|
|
- Sound picker with live preview
|
|
- Volume and vibration controls
|
|
- Snooze duration settings
|
|
|
|
### Noise Tab
|
|
1. **Sound Selection**: Browse sounds by category with system search in the navigation bar (iPhone and iPad)
|
|
2. **Sound Preview**: Long-press for 3-second preview
|
|
3. **Visual Feedback**: Grid layout with clear selection states
|
|
4. **Auto-stop**: Automatically stops current sound when selecting new one
|
|
5. **Play/Stop Controls**: Simple button with visual feedback
|
|
6. **Continuous playback**: Sounds loop until stopped
|
|
7. **Empty state guidance**: Prompt shown when no sound is selected
|
|
8. **Responsive layout**: Optimized for portrait and landscape orientations
|
|
|
|
## Technical Requirements
|
|
|
|
### iOS Compatibility
|
|
- **Minimum iOS version**: iOS 18.0+ (Latest SwiftUI features and performance optimizations)
|
|
- **Target devices**: iPhone and iPad with full adaptive layout support
|
|
- **Orientation support**: Portrait and landscape with dynamic type support
|
|
- **Accessibility**: Full VoiceOver and Dynamic Type support
|
|
|
|
### Modern iOS Technology Stack
|
|
- **SwiftUI**: Latest declarative UI framework with iOS 18+ and iOS 26 features
|
|
- **Observation Framework**: Modern @Observable pattern for state management
|
|
- **SwiftData**: Advanced data persistence with iOS 18+ SwiftData features
|
|
- **Async/Await**: Modern concurrency patterns throughout
|
|
- **Structured Concurrency**: Task groups and actors for complex operations
|
|
- **Swift 6**: Latest language features and safety improvements
|
|
- **iOS 26 Features**: Latest platform capabilities where available
|
|
|
|
### Dependencies
|
|
- **AudioPlaybackKit**: Local Swift package for reusable audio functionality
|
|
- iOS 17.0+ and tvOS 17.0+ support
|
|
- Generic sound management and configuration
|
|
- Audio playback with background support
|
|
- Wake lock management
|
|
- Modern @Observable state management
|
|
- **Bedrock**: Local Swift package for design system and settings UI
|
|
- App-wide theming with color providers
|
|
- Branded launch experience and icon tooling
|
|
- Reusable settings components (cards, toggles, sliders)
|
|
- **SwiftUI**: Native iOS UI framework with latest features
|
|
- **AVFoundation**: Audio playback with modern async patterns and background support
|
|
- **UserNotifications**: Alarm notifications with rich content support
|
|
- **Combine**: Timer publishers and reactive programming
|
|
- **Observation**: Modern state management with @Observable
|
|
- **Foundation**: Core system frameworks and utilities
|
|
- **UIKit**: UIFont integration for precise text measurement and font customization
|
|
- **UIApplication**: Screen wake lock management and idle timer control
|
|
|
|
### Build Configuration
|
|
- **xcconfig**: Centralized identifiers (bundle IDs, team ID, app groups)
|
|
- **Info.plist bridge**: App identifiers exposed via AppIdentifiers.swift
|
|
|
|
### Advanced Font and Typography Utilities
|
|
- **FontFamily enum**: Type-safe font family selection with allCases support
|
|
- **Font.Weight extension**: Enhanced weight enum with allCases and uiFontWeight properties
|
|
- **Font.Design extension**: Enhanced design enum with allCases and uiFontWidth properties
|
|
- **FontUtils.calculateOptimalFontSize()**: Binary search algorithm for precise font sizing
|
|
- **FontUtils.tightBoundingBox()**: Accurate text measurement with minimal padding
|
|
- **FontUtils.createUIFont()**: Creates UIFont instances with proper weight and design mapping
|
|
- **FontUtils.weightedFontName()**: Constructs proper font names for custom fonts
|
|
- **FontUtils.stringFromFontWeight()**: Converts Font.Weight enum to display strings
|
|
- **FontUtils.stringFromFontDesign()**: Converts Font.Design enum to display strings
|
|
- **Legacy compatibility methods**: Backward compatibility for existing code
|
|
- FontUtils.optimalFontSize() and maximumStretchedFontSize()
|
|
- FontUtils.customFont() and customUIFont()
|
|
- FontUtils.dotSizeMultiplier() and timePickerFontSize()
|
|
|
|
### Performance Considerations
|
|
- **Smart timer management**: Conditional timers based on settings
|
|
- **Debounced persistence**: Batched UserDefaults writes
|
|
- **Memory management**: Proper cleanup of audio players
|
|
- **Battery optimization**: Efficient update mechanisms
|
|
- **Color caching**: Avoid repeated hex-to-Color conversions
|
|
- **Dictionary lookups**: O(1) alarm access instead of linear search
|
|
- **Smooth animations**: Hardware-accelerated transitions
|
|
- **Preloaded audio**: Instant sound playback
|
|
- **Binary search font sizing**: O(log n) font size calculation for optimal performance
|
|
- **Tight bounding box calculations**: Precise text measurement with minimal overhead
|
|
- **Dynamic font sizing**: Real-time font optimization based on container geometry
|
|
- **Component consolidation**: Reduced view hierarchy with unified ColonView
|
|
- **Type-safe enums**: Compile-time safety eliminates runtime string conversion overhead
|
|
- **Orientation-aware sizing**: Optimized font sizing algorithms for different orientations
|
|
|
|
## Recent Architectural Improvements
|
|
|
|
### Font System Refactoring (September 2025)
|
|
- **Type-Safe Font Architecture**: Migrated from string-based font selection to enum-based system
|
|
- FontFamily enum with 10 font options (System, Helvetica, Arial, Times New Roman, Georgia, Verdana, Courier, Futura, Avenir, Roboto)
|
|
- Font.Weight extension with allCases support and uiFontWeight mapping
|
|
- Font.Design extension with allCases support and uiFontWidth mapping
|
|
- **Advanced Font Sizing**: Implemented binary search algorithm for optimal font sizing
|
|
- calculateOptimalFontSize() with tight bounding box calculations
|
|
- Real-time font size optimization based on container geometry
|
|
- Precise text measurement with minimal padding and spacing
|
|
- **Component Consolidation**: Unified colon separator components
|
|
- Replaced HorizontalColon and VerticalColon with single ColonView
|
|
- Added isHorizontal boolean parameter for orientation control
|
|
- Reduced code duplication by ~80 lines
|
|
- **Backward Compatibility**: Maintained compatibility with existing code
|
|
- Legacy methods preserved for existing functionality
|
|
- String-to-enum conversion in ClockStyle for UserDefaults persistence
|
|
- Gradual migration path for all font-related components
|
|
|
|
### Code Quality Improvements
|
|
- **Enum-Based Architecture**: Eliminated string-based font selection errors
|
|
- **Type Safety**: Compile-time safety for font family, weight, and design selection
|
|
- **Performance Optimization**: O(log n) font sizing with binary search
|
|
- **Maintainability**: Single source of truth for font options with allCases
|
|
- **User Experience**: Real-time font preview with immediate visual feedback
|
|
|
|
## Future Enhancement Opportunities
|
|
- **Additional sound types**: More white noise variants
|
|
- **Sleep timer**: Auto-stop noise after specified time
|
|
- **Widget support**: Home screen clock widget
|
|
- **Apple Watch companion**: Watch app for quick time check
|
|
- **In-app purchases**: Premium sound packs
|
|
- **Custom sounds**: User-imported audio files
|
|
- **Multiple time zones**: World clock functionality
|
|
- **Alarm categories**: Group alarms by type (work, sleep, etc.)
|
|
- **Smart alarms**: Gradual volume increase
|
|
- **Weather integration**: Weather-based alarm sounds
|
|
- **Health integration**: Sleep tracking integration
|
|
|
|
## Build and Development
|
|
|
|
### Terminal Build Commands
|
|
|
|
The following terminal commands are used for building and testing the project. These commands have been tested and work reliably:
|
|
|
|
#### Basic Build Commands
|
|
```bash
|
|
# Navigate to project directory
|
|
cd /Users/mattbruce/Documents/Projects/TheNoiseClock
|
|
|
|
# Build for iOS Simulator (iPad mini)
|
|
xcodebuild -project TheNoiseClock.xcodeproj -scheme TheNoiseClock -destination 'platform=iOS Simulator,name=iPad mini (A17 Pro),OS=18.1' build
|
|
|
|
# Build for iOS Simulator (any device)
|
|
xcodebuild -project TheNoiseClock.xcodeproj -scheme TheNoiseClock -destination 'platform=iOS Simulator,name=Any iOS Simulator Device' build
|
|
|
|
# Build for physical device (requires provisioning profile)
|
|
xcodebuild -project TheNoiseClock.xcodeproj -scheme TheNoiseClock build
|
|
```
|
|
|
|
#### Error Checking Commands
|
|
```bash
|
|
# Check for build errors only (filtered output)
|
|
xcodebuild -project TheNoiseClock.xcodeproj -scheme TheNoiseClock -destination 'platform=iOS Simulator,name=iPad mini (A17 Pro),OS=18.1' build 2>&1 | grep -E "(error:|warning:|failed)" | head -10
|
|
|
|
# Quick syntax check for specific files
|
|
swift -frontend -parse TheNoiseClock/Views/Clock/Components/TimeDisplayView.swift
|
|
swift -frontend -parse TheNoiseClock/Views/Clock/Components/TimeSegment.swift
|
|
swift -frontend -parse TheNoiseClock/Views/Clock/Components/DigitView.swift
|
|
```
|
|
|
|
#### Available Simulators
|
|
The following simulators are available for testing:
|
|
- **iPad mini (A17 Pro)** - Primary testing device
|
|
- **iPad (10th generation)**
|
|
- **iPad Air 11-inch (M2)**
|
|
- **iPad Air 13-inch (M2)**
|
|
- **iPad Pro 11-inch (M4)**
|
|
- **iPad Pro 13-inch (M4)**
|
|
- **iPhone 16, 16 Plus, 16 Pro, 16 Pro Max**
|
|
- **iPhone SE (3rd generation)**
|
|
|
|
#### Build Troubleshooting
|
|
1. **Provisioning Profile Errors**: Use iOS Simulator builds instead of device builds
|
|
2. **Missing Files**: Ensure all new Swift files are added to the Xcode project target
|
|
3. **Preview Compilation Errors**: Break down complex expressions into computed properties
|
|
4. **Package Dependencies**: AudioPlaybackKit is included as local package dependency
|
|
|
|
#### Development Workflow
|
|
1. **Make code changes** in Xcode or via AI assistant
|
|
2. **Test build** using terminal commands above
|
|
3. **Fix any errors** identified in build output
|
|
4. **Test on simulator** using Xcode or terminal build
|
|
5. **Update PRD** if architectural changes are made
|
|
|
|
## Development Notes
|
|
|
|
### Project Information
|
|
- **Created**: September 7, 2025
|
|
- **Framework**: SwiftUI with iOS 18.0+ target (latest stable features)
|
|
- **Architecture**: Modern SwiftUI with @Observable pattern, MVVM, and Swift Package modularity
|
|
- **Package Architecture**: AudioPlaybackKit Swift package for reusable audio functionality
|
|
- **Testing**: Comprehensive unit and UI test targets with Swift Testing
|
|
- **Version control**: Git repository with feature branch workflow
|
|
- **Performance**: Optimized for battery life and smooth operation
|
|
- **Modern iOS**: Uses latest iOS 18+ and iOS 26 features with Swift 6 language improvements
|
|
- **Code Reusability**: Modular Swift package architecture enables code reuse across projects
|
|
|
|
### Modern iOS Development Practices
|
|
- **Swift 6**: Latest language features including strict concurrency checking
|
|
- **Async/Await**: Modern concurrency patterns throughout the codebase
|
|
- **Observation Framework**: @Observable for reactive state management
|
|
- **SwiftUI Navigation**: Latest NavigationStack and navigation APIs with iOS 18+ features
|
|
- **Accessibility**: Full VoiceOver and Dynamic Type support with iOS 26 enhancements
|
|
- **Adaptive Layout**: Support for all device sizes and orientations
|
|
- **Performance**: Optimized for 120Hz ProMotion displays and iOS 26 performance improvements
|
|
- **Memory Management**: ARC with proper weak references and cleanup
|
|
- **Error Handling**: Result types and proper error propagation
|
|
- **Testing**: Swift Testing framework for modern test writing
|
|
- **iOS 26 Integration**: Latest platform features and capabilities where applicable
|
|
|
|
### Code Quality Standards
|
|
- **SwiftLint**: Automated code style enforcement
|
|
- **Documentation**: Comprehensive inline documentation with DocC
|
|
- **Type Safety**: Leverage Swift's type system for compile-time safety
|
|
- **Protocol-Oriented**: Use protocols for abstraction and testability
|
|
- **Dependency Injection**: Constructor injection for better testability
|
|
- **SOLID Principles**: Single responsibility, open/closed, dependency inversion
|