HomeAboutExperienceProjectsContactBlog
RésuméDex0/17
← Projects

Habit Formed

A gesture-driven habit tracker whose habits can check themselves off from Apple Health.

LOGS+5 MORESWIFTDATA11 ROWSREAD5DAYSDAILY

Daily counts back from today, or from yesterday while today isn't logged yet, and stops at the first missed day.

Tap days to log or unlog them. The streak is worked out from the rows each time, by the app's own rules. A week is a row here, and today is the outlined day.

A completion is just a row. The tile works out the streak from those rows every time it reads them, by the day, the week, or every few days.

A grid of glass tiles, one per habit, each with a streak and a seven-day dot row. Slide a knob to log, run a timer that logs for you, or link a habit to steps, sleep or exercise so it completes the moment you hit the target. Streaks follow each habit's own rhythm: daily, weekly, or every N days.

Why

Most trackers make you remember to tick things off and assume every habit is daily. The objective ones, like steps, sleep and mindful minutes, are already measured. Habit Formed reads them, and handles the habits that aren't daily, like three workouts a week or watering plants every four days.

How it's put together

IPHONEAPPLEHEALTHHEALTHKITSERVICESWIFTDATACOMPLETIONSTILE GRID@QUERYTIMERCENTERREMINDERSLIVEACTIVITYWIDGET EXT
One app, no server: a HealthKit service turns Apple Health samples into completion rows in SwiftData, and the tile grid derives every streak from those rows when it reads them. The timer keeps its own snapshot with a fixed end date outside SwiftData, so it survives the app being killed, and the Live Activity's pause button calls back into it through an App Intent.

Trade-offs

Store completions, derive streaks. One row per log with its value, so editing history can never desync a stored counter. The downside: Streaks are recomputed on read (cheap at this size).

Observers plus a poll. Background delivery is fast when it works; the poll covers the times iOS holds it back. The downside: A little foreground work every 15 seconds.

Next: ShippingEnvA from-scratch reinforcement-learning environment: haul cargo between ports on a world map.

Year
2026
Platform
iPhone
Status
Feature-complete personal app
Code
Source
Built with
Swift, SwiftUI, SwiftData, HealthKit, ActivityKit, App Intents, UserNotifications
  • 5,186 lines of Swift
  • 8 Health sources
  • 3 streak cadences
  • 0 streaks stored (all derived)