- Update App Group IDs from group.com.tt.feels to group.com.88oakapps.feels - Update iCloud container IDs from iCloud.com.tt.feels to iCloud.com.88oakapps.feels - Sync code constants with entitlements across all targets (iOS, Watch, Widget) - Update documentation in CLAUDE.md and PROJECT_OVERVIEW.md Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
5.6 KiB
5.6 KiB
Feels - iOS Mood Tracking App
Overview
Feels is a daily mood tracking iOS application that allows users to rate their emotional state each day on a 5-point scale (Horrible, Bad, Average, Good, Great) and visualize patterns over time through multiple view modes.
Core Features
- Daily Mood Tracking: Rate your day on a 5-point scale
- Multiple View Modes: Day (chronological list), Month (calendar grid), Year (aggregate stats)
- Customization: Themes, color schemes, icon packs, notification personalities
- Widgets: iOS home screen widgets showing recent moods
- Local Notifications: Daily reminders with action buttons for quick mood entry
- Data Export/Import: CSV format for data portability
- Subscription Model: 30-day free trial, then monthly/yearly subscriptions
- Localization: English and Spanish
Architecture
Pattern: MVVM (Model-View-ViewModel) with SwiftUI
Project Structure
Feels/
├── Shared/ # Core app code
│ ├── Models/ # Data models (Mood, Theme, MoodTintable, etc.)
│ ├── Views/ # SwiftUI views organized by feature
│ │ ├── DayView/ # Chronological list view
│ │ ├── MonthView/ # Calendar grid view
│ │ ├── YearView/ # Yearly statistics view
│ │ ├── CustomizeView/ # Settings and customization
│ │ └── Components/ # Reusable UI components
│ ├── Persisence/ # Core Data persistence layer
│ ├── Onboarding/ # First-run experience
│ └── Protocols/ # Protocol definitions
├── FeelsWidget/ # iOS Widget Extension (3 widget types)
├── en.lproj/ # English localization
├── es.lproj/ # Spanish localization
└── Tests iOS/ # Test targets
Key Files
App Entry
| File | Purpose |
|---|---|
FeelsApp.swift |
Main app entry, Core Data setup, IAP manager, tab navigation |
Data Layer
| File | Purpose |
|---|---|
Feels.xcdatamodeld |
Core Data model with MoodEntry entity |
Persistence.swift |
Core Data stack, App Group container |
PersistenceGET.swift |
Fetch operations |
PersistenceADD.swift |
Create/fill missing entries |
PersistenceUPDATE.swift |
Update operations |
PersistenceDELETE.swift |
Delete operations |
Main Views
| File | Purpose |
|---|---|
MainTabView.swift |
Root navigation (Day, Month, Year, Customize tabs) |
DayView.swift |
Chronological mood list with edit/delete |
MonthView.swift |
Calendar grid with color-coded moods |
YearView.swift |
Aggregate yearly statistics |
CustomizeView.swift |
Theme, colors, icons, shape settings |
Services
| File | Purpose |
|---|---|
IAPManager.swift |
StoreKit 2 subscriptions, 30-day trial |
LocalNotification.swift |
Daily reminders with quick actions |
BGTask.swift |
Background task for filling missing dates |
EventLogger.swift |
Analytics event tracking |
Data Models
MoodEntry (Core Data Entity)
- moodValue: Int16 (0-4 for mood ratings)
- forDate: Date (the day being rated)
- timestamp: Date (when entry was created)
- weekDay: Int16 (1-7)
- canEdit, canDelete: Boolean
- entryType: Int16 (header, list, filled-in-missing)
Mood Enum
enum Mood: Int {
case horrible = 0
case bad = 1
case average = 2
case good = 3
case great = 4
case missing = 5
case placeholder = 6
}
Customization System
Themes (Theme.swift)
- System, iFeel (gradient), Dark, Light
- Protocol:
Themeable
Color Schemes (MoodTintable.swift)
- Default, Neon, Pastel, Custom (user-defined)
- Each mood has primary and secondary colors
Icon Packs (MoodImagable.swift)
- FontAwesome, Emoji, Hand Emoji
- Protocol:
MoodImagable
Shapes
- Circle, Square, Diamond for calendar visualization
Notification Personalities (PersonalityPackable.swift)
- "Nice": Friendly text
- "Rude": Sarcastic/aggressive text
Widget System
Three widget types in FeelsWidget/:
- FeelsWidget: Small/Medium/Large showing recent moods
- FeelsGraphicWidget: Small widget with mood graphic
- FeelsIconWidget: Custom icon widget
Data shared via App Groups: group.com.88oakapps.feels
Dependencies
Apple Frameworks
- SwiftUI, CoreData, WidgetKit, StoreKit, UserNotifications, CloudKit, BackgroundTasks
Third-Party
- CloudKitSyncMonitor
- Firebase (GoogleService-Info.plist)
Configuration
App Groups
- Production:
group.com.88oakapps.feels - Debug:
group.com.88oakapps.feels.debug
Background Tasks
- Identifier:
com.88oak.Feels.dbUpdateMissing
StoreKit Products
- Monthly subscription
- Yearly subscription
- 30-day free trial
Data Flow
User Input → Persistence (Core Data) → ViewModel Update → SwiftUI Re-render
↓
Widget Update (WidgetCenter.shared.reloadAllTimelines())
Localization
| Language | File |
|---|---|
| English | en.lproj/Localizable.strings |
| Spanish | es.lproj/Localizable.strings |
Covers: Onboarding, mood names, UI labels, notifications, settings
Notable Implementation Details
- Automatic Missing Date Fill: Creates placeholder entries for days without ratings
- Entry Types:
header,listView,filledInMissing- tracks how entries were created - Day Filtering: Users can filter which weekdays appear in visualizations
- CSV Export: Full data portability with all metadata preserved