Export and Import Services

ExportService

Protocol

protocol ExportService {
    func exportToCSV(
        records: [TimeRecord],
        tags: [Tag],
        options: ExportOptions
    ) -> Data
}

CSV Format

Date,Start Time,End Time,Duration,Tag,Comment
2024-01-15,09:30,11:45,2:15,Work,Working on feature X

Export Options

  • Date range filtering
  • Tag filtering
  • Include/exclude untagged
  • Include/exclude running timers
  • Column selection

Implementation

DefaultExportService in Shared/Sources/MinutaShared/Services/ExportService.swift

ImportService

Protocol

protocol ImportService: Sendable {
    func parseHEYCSV(_ content: String, existingTags: [Tag]) -> (records: [ParsedRecord], newTags: [Tag])
}

HEY CSV Format

Start,End,Duration,Category,Notes
2024-01-15 09:30,2024-01-15 11:45,2:15,Work,Working on feature X
  • Dates: YYYY-MM-DD HH:mm
  • Duration is ignored (calculated from start/end)
  • Category maps to tag name
  • Notes maps to comment

ParsedRecord

struct ParsedRecord: Sendable {
    let startTime: Date
    let endTime: Date
    let categoryName: String?
    let notes: String?
}

Import Flow

  1. Parse CSV to get ParsedRecord array and new tags
  2. Create new tags (auto-assigned random colors from ColorPalette)
  3. Build tag name -> UUID lookup
  4. Create TimeRecord for each ParsedRecord with resolved tagId
  5. Save records via TimeTrackingService

Implementation

HEYImportService in Shared/Sources/MinutaShared/Services/ImportService.swift

Uses CSVParser utility for proper field parsing (handles quoted fields, embedded commas).

UI Integration

Export

  • HistorySection uses fileExporter modifier for save panel
  • ShareLink for system share sheet
  • Generates CSV inline using DurationFormatter and CSVParser

Import

  • SettingsSheet uses fileImporter modifier
  • Processes file with HEYImportService
  • Shows success/error message

Related

Models

Services

UI