App Settings
Relevant source files
The following files were used as context for generating this wiki page:
- Features/SettingsFeature/Sources/SettingsFeature/Views/SettingsRoot/SettingsRootView.swift
- Features/SettingsFeature/Sources/SettingsFeature/Views/SettingsRoot/SettingsRootViewModel.swift
- Trackurr/Dependencies/Persistence/Migration/SchemaV5.swift
- Trackurr/Dependencies/Persistence/Migration/AppMigrationPlan.swift
- Features/AppFeature/Tests/AppFeatureTests/Views/AppRootViewModelTests.swift
- TrackurrTests/Persistence/Stores/DataExportServiceTests.swift
The App Settings module provides a centralized interface for users to manage their personal preferences, subscription status, data synchronization, and application-wide configurations. It acts as the primary gateway for customizing the user experience, including visual appearance, functional behaviors like haptic feedback, and data management tasks such as backups and exports.
Architecturally, the settings system is built using a modern SwiftUI approach, utilizing the @Observable framework for state management and the Factory pattern for dependency injection. This ensures a decoupled and testable structure where user preferences are persisted locally via SwiftData and synchronized across devices through CloudKit integration.
Sources: README.md, Features/SettingsFeature/Sources/SettingsFeature/Views/SettingsRoot/SettingsRootViewModel.swift:10-14, Features/SettingsFeature/Sources/SettingsFeature/Views/SettingsRoot/SettingsRootView.swift:11-15
Architecture and Data Flow
The Settings feature follows the MV (Model-View) pattern enhanced by specialized services. The SettingsRootView serves as the primary UI, while SettingsRootViewModel handles the logic, interacting with various stores and monitors.
Component Interaction
The following diagram illustrates the relationship between the Settings UI and the underlying system services:
When a user modifies a setting (e.g., toggling Haptic Feedback), the View Model updates the local Preferences model and calls the PreferencesStore to persist the change. Upon a successful save, an event is published to the AppEventBus to notify other parts of the app (like the Root View) to refresh their state.
Sources: Features/SettingsFeature/Sources/SettingsFeature/Views/SettingsRoot/SettingsRootViewModel.swift:23-55, Features/SettingsFeature/Sources/SettingsFeature/Views/SettingsRoot/SettingsRootViewModel.swift:125-133, Features/AppFeature/Tests/AppFeatureTests/Views/AppRootViewModelTests.swift:236-245
Data Models and Persistence
Preferences Entity
The core of the settings system is the Preferences entity. This model has evolved through schema migrations to support growing app requirements.
| Field | Type | Default | Description |
|---|---|---|---|
defaultCurrencyCode | String | "USD" | Default currency for new subscriptions |
dateFormatPreference | Enum | .system | User-selected format for displaying dates |
firstDayOfWeek | Enum | .system | Start of the week in calendar views |
hapticFeedbackEnabled | Bool | true | Toggle for tactile feedback |
appearanceMode | Enum | .system | Light, Dark, or System theme selection |
Sources: Trackurr/Dependencies/Persistence/Migration/SchemaV5.swift:168-185, Trackurr/Dependencies/Persistence/Migration/SchemaV2.swift:150-165
Schema Migrations
The app employs a versioned schema migration plan to ensure data integrity as the Preferences model changes. Notable transitions include:
- V1 -> V2: Introduction of the
Preferencesentity. - V4 -> V5: Addition of the
appearanceModeattribute.
Sources: Trackurr/Dependencies/Persistence/Migration/AppMigrationPlan.swift:34-37, Trackurr/Dependencies/Persistence/Migration/AppMigrationPlan.swift:49-52
Feature Management
Premium Status
The system manages access to premium features through a dedicated section in the settings. It identifies the user's current plan (Monthly, Annual, or Lifetime) and provides links to manage subscriptions via StoreKit 2.
Feature Flags and Developer Options
In debug builds, a "Developer" section is available to toggle feature flags. This allows for testing experimental features like "Calendar Icon Indicators" without affecting production users.
Sources: Features/SettingsFeature/Sources/SettingsFeature/Views/SettingsRoot/SettingsRootViewModel.swift:88-100, Features/SettingsFeature/Sources/SettingsFeature/Views/SettingsRoot/SettingsRootView.swift:277-299
Synchronization and Data Portability
iCloud Integration
Settings monitors the status of CloudKit synchronization through the CloudSyncMonitor. The UI displays statuses such as synced, syncing, accountUnavailable, or error, along with the last successful sync timestamp.
Sources: Features/SettingsFeature/Sources/SettingsFeature/Views/SettingsRoot/SettingsRootView.swift:145-164, Features/SettingsFeature/Sources/SettingsFeature/Views/SettingsRoot/SettingsRootView.swift:180-210
Backup and Export
Users can export their entire application state (Subscriptions, Categories, Tags, and Preferences) into a JSON format. The DataExportService handles both the generation of these backups and the restoration process, which includes deduplication logic to prevent redundant entries during import.
Sources: TrackurrTests/Persistence/Stores/DataExportServiceTests.swift:65-80, TrackurrTests/Persistence/Stores/DataExportServiceTests.swift:125-135, Features/SettingsFeature/Sources/SettingsFeature/Views/SettingsRoot/SettingsRootView.swift:239-251
Summary
The App Settings module is a robust subsystem that handles user configuration, premium access, and data portability. By leveraging a modular architecture and SwiftData persistence, it provides a seamless experience for users to tailor the application to their needs while ensuring their data remains synchronized and recoverable.