43 KiB
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
- Full-screen mode with status bar hiding and tab bar expansion
- Orientation-aware spacing for optimal layout in all orientations
2. Clock Customization
- 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 automatically hidden in 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)
- White Noise (
- 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
- 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
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
- 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: Automatic status bar hiding in full-screen mode
- 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:
Soundmodel: Generic sound data structure with Codable support and GUID generationSoundConfigurationmodels: Configuration structures for sound managementSoundConfigurationService: Generic sound configuration service with JSON loadingNoisePlayer: Audio playback service with background supportWakeLockService: Screen wake lock managementNoiseViewModel: Audio playback state managementAudioConstants: 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
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
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
│ │ │ ├── UIConstants.swift # UI constants namespace
│ │ │ ├── UIConstants+Colors.swift # Theme-backed colors
│ │ │ ├── UIConstants+Layout.swift # Spacing/radius/opacity
│ │ │ ├── UIConstants+Animation.swift # Animation curves
│ │ │ └── Fonts/
│ │ │ ├── Font.Design.swift
│ │ │ ├── Font.Weight.swift
│ │ │ ├── FontFamily.swift
│ │ │ └── FontUtils.swift
│ │ ├── Theme/
│ │ │ └── NoiseClockTheme.swift # Bedrock app color theme
│ │ ├── 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
│ │ ├── DebugLogger.swift # Debug logging helper
│ │ └── NotificationUtils.swift # Notification helper functions
│ ├── 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
│ │ │ ├── ClockTabBarManager.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
│ │ │ └── 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
│ └── 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+Extensionsformat (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:
- Identify PRD sections that need updating based on the changes made
- Update relevant sections without being asked
- Add new features to the appropriate feature sections
- Update file structure when new files or components are created
- Document new requirements or architectural decisions
- 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
Key User Interactions
Clock Tab
- View time: Real-time clock display
- Access settings: Tap gear icon in navigation bar
- Enter display mode: Long-press anywhere on clock (0.6 seconds)
- Exit display mode: Long-press again to return to normal mode
Settings
- Time format: Toggle 24-hour, seconds, AM/PM display
- Appearance: Adjust colors, glow, size, opacity
- Display: Control keep awake functionality for display mode
- Focus Modes: Control how app behaves with Focus modes (Do Not Disturb)
- Overlays: Control battery and date display
- Background: Set background color and use presets
Alarms Tab
- View alarms: List of all created alarms with labels and repeat schedules
- Add alarm: Tap + button to create new alarm with full editor
- Edit alarm: Tap any alarm to open comprehensive editor
- Toggle alarm: Use switch to enable/disable
- Delete alarm: Swipe to delete or use delete button in editor
- 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
- Sound Selection: Browse sounds by category with search functionality
- Sound Preview: Long-press for 3-second preview
- Visual Feedback: Grid layout with clear selection states
- Auto-stop: Automatically stops current sound when selecting new one
- Play/Stop Controls: Simple button with visual feedback
- Continuous playback: Sounds loop until stopped
- 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
# 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
# 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
- Provisioning Profile Errors: Use iOS Simulator builds instead of device builds
- Missing Files: Ensure all new Swift files are added to the Xcode project target
- Preview Compilation Errors: Break down complex expressions into computed properties
- Package Dependencies: AudioPlaybackKit is included as local package dependency
Development Workflow
- Make code changes in Xcode or via AI assistant
- Test build using terminal commands above
- Fix any errors identified in build output
- Test on simulator using Xcode or terminal build
- 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