iOSiOS APP

WorkTrack

Log your hours by voice. Let Claude write your timesheet summary.

SwiftSwiftUISwiftDataClaude HaikuSpeech FrameworkEventKitiOS 16+
WorkTrack

Swift · SwiftUI · SwiftData · Claude Haiku

0
Entry time by voice
0
On-device persistence
0
AI response types
0
Claude Haiku response

OVERVIEW

|

Freelance and part-time workers squeeze work into fragmented windows across the day. Logging these sessions manually was either forgotten mid-session or recorded inaccurately. No tool combined voice-first entry, a visual hours overview, and AI-generated timesheet summaries in one place.

|

A SwiftUI app built on SwiftData. The primary input is a Claude Haiku chat interface, the user speaks or types what they worked on, and the streaming AI extracts date, start/end time, and notes from natural language. A custom intensity-map calendar gives an at-a-glance overview. Confirmed entries are written to iOS Calendar via EventKit. At week's end, Claude generates a professional timesheet narrative from all entries.

|

Work sessions logged in under 10 seconds by voice. The weekly AI summary turns scattered notes into a professional timesheet narrative ready to paste directly into an invoice.

KEY FEATURES

Streaming Claude Chat

ClaudeService.swift posts to the Anthropic API with stream:true. Responses arrive as SSE events parsed via session.bytes(for:). Partial JSON updates the chat UI live as Claude types; the complete response creates the work entry.

TECH STACK

Tap to see the reasoning

BUILD TIMELINE

Phase 01

SwiftData & Calendar

Built the @Model WorkEntry and NoteEntry classes, WorkHoursStore CRUD layer, and CustomCalendarView with intensity-map colour coding. Integrated EventKit with requestAccess() on first launch.

CHALLENGES & SOLUTIONS

The streaming response arrives as fragmented JSON. The message field can be extracted from partial JSON for live display; the full entry data (date, startTime, endTime) must wait for the complete response. ClaudeService implements two separate parse functions, one for the display field and one for the action data.

New fields added in updates require schema migration. MigrationManager.swift implements a versioned migration pipeline, each step is a separate function applied in sequence. The app never loses existing work entries on update.

LET'S BUILD SOMETHING TOGETHER

I'm always open to discussing new projects, partnerships, or just a good idea.