File-Specific Implementation Notes¶
This document contains detailed implementation notes for specific files in the Nutri-E codebase. These notes highlight critical patterns, line-specific logic, and gotchas that developers should be aware of.
Table of Contents¶
Views¶
TodayView.swift¶
- StarredNutrientsSection: Displays pinned nutrients with dual progress bars (RDA + Max Intake)
- Default tab logic: Opens Today tab if user has supplements, Supplements tab if empty
- Streak counter: Shows consecutive days streak (fixed to count days, not individual doses)
ScheduleProfileView.swift¶
- Color/Icon pickers: Must use
.buttonStyle(BorderlessButtonStyle())for buttons in Form LazyVGrid - Color extension:
Color(colorName:)converts string color names to SwiftUI Color values
AddScheduleView.swift¶
- Auto-populate dose:
.onChange(of: selectedSupplement)sets doseAmount from supplement.doseAmount
SupplementSearchView.swift¶
- Line 602-610: Form classification logic - DosageFormService lookup BEFORE unit-based override
- Line 675-686: Fractional serving size parsing with regex pattern
- Line 723: Unit normalization mapping
- @FocusState: Auto-focus search field when view appears
NutrientDetailView.swift¶
- getRelevantUnits(): Must include .kcal for calories editing
- refreshTrigger pattern: Use @State + .id() for immediate view updates
DataManagementView.swift¶
- Export options:
- Export to file: Creates
.jsonfile with date-stamped filename - Share sheet for AirDrop, Files, email
- Import options:
- Import from file: Standard file picker
- Paste JSON: Direct JSON paste from clipboard (added Oct 2024)
- Auto-pastes clipboard content when opened
- Import confirmation: Shows destructive alert before replacing all data
- Data statistics: Shows supplement count, dose count, and days of data tracked
- Error handling: Validates JSON before import, shows user-friendly error messages
MoreView.swift¶
- Device ID display: Shows first 12 characters in About section (lines 108-123)
- Long-press context menu to copy full Device ID
- Used for customer support and debugging
- Format:
ABC123XYZ...with monospaced font - Developer Tools: Wrapped in
#if DEBUGflag (lines 85-96) - Only visible in debug builds
- Hidden in production/TestFlight/App Store builds
Services¶
ScheduleService.swift¶
- Time-based sorting: Sorts schedules by hour/minute components (lines 176-188)
- In-memory sort: Extracts Calendar components to ensure proper chronological order
StreakTrackingService.swift¶
- Consecutive days logic: Counts unique days with doses, not individual dose count (fixed Oct 2024)
- De-duplication: Skips doses on same day using
lastCountedDaytracking
DataExportService.swift¶
- Complete data export/import: Exports supplements, doses, schedules, profiles, and user profile to JSON
- CRITICAL FIELDS: Must include
servingSizeandservingUnitfor Individual Dose data integrity servingSize: Individual Dose amount (stored as String, e.g., "0.5")servingUnit: Individual Dose unit (stored as String, e.g., "mL")- Without these fields, Individual Dose defaults to "1" after import (data corruption)
- Export format: Pretty-printed JSON with ISO8601 dates
- Import process: Batch deletes all existing data, calls
viewContext.reset(), then imports fresh data - Version: Currently "1.0" format
DosageFormService.swift¶
- 31 supported forms: Capsule, Tablet, Lozenge, Powder, Liquid, etc.
- Synonyms support: "gummi bear" → "Gummy", "ampoule" → "Lozenge"
- Category mapping: Each form maps to .solid, .liquid, .powder, .topical, .other
Utils¶
SupplementDisplayFormatter.swift¶
- formatDoseDisplay(): Handles individual vs serving size display
- pluralizeUnit(): Count-based units get pluralized, weight/volume don't
- formatStockCount(): Decimals for powder/liquid, integers for solids
Models¶
UnitType.swift¶
- Categories: .weight, .volume, .energy, .count, .internationalUnits
- Conversions: Built-in conversion logic between related units
- Display: Always use .displayName for UI, never raw values
Notes¶
When to update this file: - Adding new critical patterns or gotchas - Fixing bugs that require line-specific explanations - Documenting non-obvious implementation details
When NOT to use this file: - General architectural patterns (put in CLAUDE.md) - API documentation (put in API_REFERENCE.md) - User-facing documentation (put in README.md)
Better alternatives: - Add inline code comments for complex logic - Use descriptive function/variable names - Write unit tests that document expected behavior