9.4 KiB
9.4 KiB
Rituals (Andromida)
Rituals is a paid, offline-first habit tracker built around customizable "ritual" arcs. It focuses on steady, daily check-ins with a calm visual language, zero paid backend dependencies, and optional iCloud sync for settings.
Overview
- Concept: Habits are grouped into ritual arcs (7-365 days) rather than endless streaks.
- Tech: SwiftUI + SwiftData, Clean Architecture layering, Bedrock design system.
- Data: Local persistence with SwiftData; settings sync via Bedrock CloudSyncManager (NSUbiquitousKeyValueStore).
- No paid APIs: No external services required.
Feature Set
Today Tab
- Focus ritual cards with progress rings
- Tap-to-complete habit check-ins with haptic/sound feedback
- Time-of-day filtering (morning, midday, afternoon, evening, night, anytime)
- Smart empty states (distinguishes "no rituals" from "no rituals for this time")
- Fresh install starts clean (no pre-seeded rituals)
Rituals Tab
- View all active rituals
- Create new rituals from scratch or browse preset library
- 14 categorized presets (Health, Productivity, Mindfulness, Self-Care)
- Full ritual management: edit, enable/disable, archive, delete
- Drag-to-reorder habits within rituals
Ritual Detail View
- Progress card with day count and completion summary
- Time remaining countdown ("12 days remaining")
- Ritual-specific streak tracking
- Milestone achievements (Day 1, Week 1, Halfway, Complete)
- Habit performance breakdown with completion rates
- Status badges (time of day, category, enabled/disabled)
- Action menu for edit, archive, and delete
Ritual Editor
- Custom ritual creation with title, theme, notes
- Icon picker with 50+ categorized SF Symbols and search
- Habit icon picker with 100+ icons organized by category
- Custom category input (beyond preset categories)
- Flexible duration: slider (7-365 days) + quick presets + custom input
- Time-of-day scheduling (morning, midday, afternoon, evening, night, anytime)
- Drag-to-reorder habits
History Tab
- Scrollable month calendar grid
- Daily progress rings with color coding (green=100%, accent=50%+, gray=<50%)
- Filter by ritual using horizontal pill picker
- "All" mode includes historical data from completed and archived arcs
- Tap any day for detail sheet showing:
- Progress ring with percentage
- Comparison to weekly average
- Streak context (if part of a streak)
- Motivational message
- Grouped habit list by ritual
Insights Tab
- Tappable insight cards with full-screen detail sheets
- Active Rituals: Count with per-ritual breakdown
- Streak: Current and longest perfect-day streak tracking (100% completion days)
- Habits Today: Completed count with per-ritual breakdown
- Completion: Today's percentage with 7-day trend chart
- Days Active: Total active days with detailed breakdown (first check-in, most recent, per-ritual counts)
- 7-Day Avg: Weekly average completion percentage with trend chart
- Total Check-ins: All-time habit completions across all rituals
- Best Ritual: Highest-performing ritual by completion rate in the current arc
- Trend indicators (up/down/stable) with week-over-week comparison
- Contextual tips based on performance
Settings Tab
- Smart reminders based on ritual time-of-day (morning/midday/evening)
- Haptics and sound toggles (wired to habit check-ins)
- iCloud settings sync
- Debug tools: reset onboarding, app icon generation, branding preview
Widget Behavior Notes
- "Next ritual" messaging explicitly distinguishes later-today vs tomorrow scheduling.
- Timeline calculations use in-progress arc detection for the target date.
Onboarding
- Setup wizard on first launch (goal, time, ritual preview, first check-in)
- Ends with a quick orientation to Today, Rituals, and Insights
- Debug reset available in Settings
Branding & Launch
- Bedrock AppLaunchView with custom theme
- Native LaunchScreen.storyboard (no white flash)
- Dark theme enforced throughout
- Centralized branding config (colors, icons, launch)
Architecture
This project follows Clean Architecture and protocol-first design:
- Views: SwiftUI UI only, no business logic
- State: @Observable stores with app logic
- Services: Stateless logic and data seeding
- Models: SwiftData models and plain structs. The architecture is built around Ritual Arcs, allowing rituals to be renewed while preserving historical accuracy.
- Protocols: Abstractions for stores/services
Project Structure
Andromida/
├── Andromida/ # App target
│ ├── App/
│ │ ├── Models/ # SwiftData + DTOs
│ │ │ ├── Ritual.swift
│ │ │ ├── RitualArc.swift
│ │ │ ├── ArcHabit.swift
│ │ │ ├── HabitCompletion.swift
│ │ │ ├── InsightCard.swift
│ │ │ ├── Milestone.swift
│ │ │ ├── TrendDirection.swift
│ │ │ └── RitualPresets.swift
│ │ ├── Protocols/ # Interfaces for stores/services
│ │ │ ├── RitualStoreProviding.swift
│ │ │ ├── RitualSeedProviding.swift
│ │ │ └── InsightTipsProviding.swift
│ │ ├── Services/ # Stateless logic
│ │ │ └── RitualSeedService.swift
│ │ ├── State/ # @Observable stores
│ │ │ ├── RitualStore.swift
│ │ │ ├── CategoryStore.swift
│ │ │ └── SettingsStore.swift
│ │ └── Views/ # SwiftUI features + components
│ │ ├── Today/
│ │ ├── Rituals/
│ │ ├── History/
│ │ ├── Insights/
│ │ └── Settings/
│ ├── Shared/ # Bedrock theme + branding config
│ └── Resources/ # LaunchScreen.storyboard
├── AndromidaTests/ # Unit tests
└── AndromidaUITests/ # UI tests
Key Files
- App entry & launch:
Andromida/Andromida/AndromidaApp.swift - Bedrock theme:
Andromida/Andromida/Shared/Theme/RitualsTheme.swift - Branding config:
Andromida/Andromida/Shared/BrandingConfig.swift - Launch screen:
Andromida/Andromida/Resources/LaunchScreen.storyboard - Ritual store:
Andromida/Andromida/App/State/RitualStore.swift - Settings store:
Andromida/Andromida/App/State/SettingsStore.swift - Settings UI:
Andromida/Andromida/App/Views/Settings/SettingsView.swift
Data Model
- Ritual: Title, theme, notes, defaultDurationDays, timeOfDay, iconName, category, sortIndex, arcs (relationship)
- RitualArc: Start date, end date, arc number, isActive, habits (relationship)
- ArcHabit: Title, symbolName, goal, completedDayIDs, sortIndex
- Milestone: Day, title, symbolName, isAchieved
- Settings: Stored via Bedrock CloudSyncManager (NSUbiquitousKeyValueStore)
Bedrock Integration
- Theming: App-specific color providers +
AppSurface,AppAccent, etc. - Branding: AppLaunchView, AppIconConfig, LaunchScreenConfig
- Settings UI: SettingsToggle, SettingsSlider, SettingsSegmentedPicker, SettingsCard
- Cloud Sync: iCloud sync for settings using CloudSyncManager
- Onboarding: Custom
SetupWizardViewflow (Sherpa integration pending)
Localization
String catalogs are used for English (en), Spanish (es-MX), and French (fr-CA):
Andromida/Andromida/App/Localization/Localizable.xcstrings
Requirements
- iOS 18.6+
- Swift 5 (Bedrock requires Swift 6 in package; app builds under Swift 5 with modern concurrency)
Running
- Open
Andromida.xcodeprojin Xcode. - Build and run on iOS 18+ simulator or device.
Tests
- Unit tests in
AndromidaTests/ - Run via Xcode Test navigator or:
xcodebuild test -scheme Andromida -destination 'platform=iOS Simulator,name=iPhone 17 Pro Max,OS=26.2'
- XCTest runs disable SwiftData CloudKit mirroring in the host app to keep simulator tests deterministic.
RitualStoreTestsuse a shared in-memory SwiftData container with per-test cleanup to avoid host-process container churn.AndromidaUITestsLaunchTestsruns a single launch configuration to reduce flaky simulator timeouts.AndromidaUITestslaunch withUITEST_MODE=1, forcing in-memory SwiftData and optional launch-state overrides (UITEST_RESET_USER_DEFAULTS,UITEST_HAS_COMPLETED_SETUP_WIZARD) for deterministic UI runs.- UI coverage includes stable onboarding-state transition validation and ritual creation from the Rituals tab.
Notes
- App is configured with a dark theme; the root view enforces
.preferredColorScheme(.dark)to ensure semantic text legibility. - Setup wizard and root shell animations respect the iOS Reduce Motion accessibility setting.
- The launch storyboard matches the branding primary color to avoid a white flash.
- iCloud sync configuration includes
com.apple.developer.ubiquity-kvstore-identifier; enableremote-notificationbackground mode via Xcode Capabilities when CloudKit push handling is needed. - App icon generation is available in DEBUG builds from Settings.
- Fresh installs start with no rituals; users create their own from scratch or presets.
- A startup data-integrity migration normalizes arc date ranges, in-progress arc state, and sort indexes.
- Date-sensitive analytics in
RitualStoreare driven by an injectable time source for deterministic tests.