MEL - App Architecture
MEL is built using modern iOS development practices with SwiftUI and follows clean architecture principles for maintainable, reliable data collection.
Data Models
Core Entities
- Collection: Name, description, date, username, and items.
- CollectionItem: Unified item type:
- As a note: title, description, timestamp, optional latitude/longitude.
- As a note with session: title, description, timestamp, optional latitude/longitude, startEvent, events ("A", "B", "C"), stopEvent, computed duration, eventCount.
- Event: id, timestamp, eventType ("A", "B", "C", "Start", "Stop").
- EventType: UI-facing enum for color and recordable events.
Relationships
- A Collection has many CollectionItem.
- An item is either a note or note-with-events.
- Items can include optional location data.
State Management
CollectionManager
- ObservableObject (per-screen lifecycle): Created/owned by views; not a singleton.
- UI State: state (.setup/.recording), elapsedTime, eventCounts, itemLocation.
- Current Context: currentCollection, currentFileURL, lastSavedFileURL, currentItem.
- Session Control: startRecording(), logEvent(type:), stopRecording(), background/foreground handling, 1s display timer, 5s autosave timer.
- Item CRUD: addNoteToCurrentCollection, updateNoteInCurrentCollection, deleteNoteFromCurrentCollection, updateItemDetails, updateCurrentItemDescription, createItemWithoutRecording.
- Resumption: resumeRecording(from:...) loads an existing collection and continues.
- Location: Owns CLLocationManager; respects AppState.shared.locationEnabled.
AppState
- Singleton: AppState.shared.
- Settings: @AppStorage for username, locationEnabled, displayMode.
- Display Mode: Applies UIUserInterfaceStyle to the active UIWindow.
- Versioning: appVersion, buildNumber, versionAndBuild.
Data Flow
Collection Lifecycle
- Create/Resume → CollectionManager context set (and optional item pre-creation).
- Modify → User actions update state; autosave every 5s if recording.
- Stop/Save → Persist via FileManagerService.saveCollection.
- Export → Convert to JSON/Markdown/Text and share.
Session Management
- Start → Create startEvent and current item; begin timers.
- Record → logEvent(type:) captures timestamps; counts A/B/C.
- Stop → Add stopEvent; save to file; clear item state.
Note Management
- Create → Build CollectionItem without events.
- Edit → Update title/description/timestamp/location; persist.
- Delete → Remove from collection; persist.
UI Architecture
SwiftUI Patterns
- NavigationStack for flow.
- Sheets for add/edit and export.
- @StateObject/@ObservedObject with @Published bindings.
View Hierarchy (current)
- HomeView
- CollectionListView (lists saved collections)
- CollectionView (details for a collection)
- CollectionItemTimelineView (unified timeline: notes + sessions)
- CollectionItemView (view/edit a single item)
- CollectionItemSetupView (prepare/start recording)
- CollectionView (details for a collection)
- CollectionNewView (create a new collection)
- SettingsView
- CollectionListView (lists saved collections)
- LaunchScreenView
Key UI Concepts
- Unified Timeline: Notes and sessions in chronological order.
- Reactive Updates: @Published drives live UI for timers, counts, and edits.
- Consistent Modals: Sheets for creation/editing and sharing.
External Services
FileManagerService
- Singleton: shared.
- Persistence: JSON encode/decode with ISO8601 dates.
- Export: exportCollection(_:as:) → .json, .markdown, .text.
- Utilities: List, delete, delete-all JSON files.
DateFormatterService
- Singleton: shared.
- Formatting: ISO8601 with fractional seconds; display, duration, filenames.
- Timestamps: createTimestamp() ensures consistent ISO dates.
CoreLocation
- Optional per settings; captured at item creation.
- CLLocationManagerDelegate inside CollectionManager.
- Starts updates when authorized and enabled; stops after capture.
File Structure
Core
- Core/Models/AppState.swift
- Core/Services/DateFormatterService.swift
- Core/Services/FileManagerService.swift
- Core/Views/HomeView.swift
- Core/Views/SettingsView.swift
- Core/Views/LaunchScreenView.swift
Collections
- Collections/Models/Collection.swift
- Collections/Models/CollectionManager.swift
- Collections/Views/CollectionListView.swift
- Collections/Views/CollectionView.swift
- Collections/Views/CollectionItemTimelineView.swift
- Collections/Views/CollectionItemView.swift
- Collections/Views/CollectionItemSetupView.swift
- Collections/Views/CollectionNewView.swift
Assets
- App icons, splash images, and logo in Assets.xcassets.
Technical Decisions
Architecture
- MVVM: Views observe CollectionManager and AppState.
- Singletons: AppState, FileManagerService, DateFormatterService.
- Per-Flow Manager: CollectionManager scoped to the recording/editing flow.
- File-Based Storage: Local JSON, human-readable, portable.
Performance
- Autosave: Fixed 5s interval during recording.
- Display Timer: 1s updates for elapsed time.
- Efficient Serialization: Pretty-printed JSON with custom date strategies.
Security & Privacy
- Location Opt-In: Disabled by default; user-controlled.
- Local-Only Data: No cloud sync; files sandboxed per app.
- Granular Collections: Each collection isolated in its own file.
Development Notes
Dependencies
- SwiftUI: iOS 16+ UI.
- CoreLocation: Optional location capture.
- Foundation: Files, dates, and encoding.