Blog

My Workout System Is an iPhone App Now. Claude and I Built It in a Day.

From a blog post about talking to my phone at the gym to a TestFlight beta with subscriptions, in one working day. Here is the receipt.

My Workout System Is an iPhone App Now. Claude and I Built It in a Day.

A few weeks ago I wrote about logging every workout by talking to my phone. The system was a Claude skill, a folder of markdown files in my Obsidian vault, and my Apple Watch, all wired together through BlackOps. It worked. It still works. I logged sixty-plus workouts with it. But it required my exact setup: my vault, my workspace, my API keys. Nobody else could use it without building their own.

Yesterday morning I opened Claude Code and typed roughly this: "Look at my notes and my blog post about how I use Claude to track my workouts. I would like to plan an iOS app that gives me the same functionality."

By dinner the app was on TestFlight. It has a name, an icon, a backend, subscriptions, and one paying customer (me, with a fake sandbox dollar). My wife is already on the beta. This post is the receipt for what happened in between.

The system was already designed

Here is the thing that made a one-day build possible. The hard part of this app was never the Swift code. The hard part was figuring out what the thing should do, and I had already done that by accident, by capturing every gym session in BlackOps for six weeks and writing about it.

The blog post described a brain (a folder of exercise files that compiles into one queryable context) and a skill (instructions that teach Claude to parse "3 sets of 10 at 60" into a table row, create files for new machines from photos, and pull heart rate data from my watch).

The app is those two ideas wearing a native UI. The brain became a function that compiles my workout history out of a local database into the prompt. The skill became four tools the app executes on the phone: log a strength set, log cardio, fetch full history for one exercise, read the latest Apple Watch workout from HealthKit. Claude calls the tools, the app writes the database, the chat bubble says "that's up 5 lbs from Tuesday."

Same shape. Different container. The six weeks of dictating sets into a chat window turned out to be the product spec.

The model I was trying not to use

A confession for the model watchers: this was all done with Claude Fable 5, and I had no intention of using Fable 5.

July 7 was circled on every AI calendar and I figured the odds were good it would land API only. I did not want to spend a week getting used to something and then be disappointed when the date came around, so I decided sticking with Opus was the safe bet and I would just avoid the new one entirely.

But here we are. It showed up in Claude Code, it is what answered when I typed that first prompt, and it built this app end to end: the Swift, the server, the App Store paperwork, this blog post's first draft, all of it. I never made a decision to adopt it. It was just driving when the day started, and by dinner the question of whether I would use Fable 5 had answered itself.

One thing to keep straight: Fable 5 was the builder, not the engine. The app itself routes to cheaper models, a fast one for everyday logging turns and a bigger one for weekly recaps, because nobody needs a frontier model to parse "3 sets of 10 at 60."

What Claude actually did

I want to be precise about the division of labor, because "I built an app in a day with AI" usually hides the interesting part.

Claude read the original blog post and my fitness notes out of BlackOps, wrote a plan document, and then built the app: SwiftUI, SwiftData, a chat tab with dictation and photo input, history charts, weekly trends, local notifications for gym gaps. It reused the project conventions from another app of mine without being told twice.

Then it built the part that makes this a product instead of a toy. Nobody downloading a fitness app is going to paste in an Anthropic API key. So there is now a small server that holds my key, meters usage per person, and routes everyday logging turns to a cheap fast model while weekly recaps get the big one. You sign in with Apple. Free plan gets 15 coach messages a month plus unlimited manual logging. Spotter Pro is $5.99 a month or $49.99 a year.

Claude also drove my actual browser through the Apple Developer portal and App Store Connect. It registered the bundle ID, checked the HealthKit and Sign in with Apple boxes, created the app record, created the subscription group, set prices in 175 regions, filled in the beta review notes, and submitted the build for external review. I watched it click through Apple's web forms the way I would, except it didn't sigh.

Eleven pull requests merged. Six architecture decision records written, because I told it early that every decision goes in the repo, and it held itself to that better than I would have.

What I did

Signed the Apple Developer Program license agreement. Signed the Paid Apps agreement. Filled in a W-9 and a bank account, because Apple will not sell a subscription for you until it knows where to send the money and what to tell the IRS. Typed my phone number into a form. Granted some macOS permissions. Said "merge it" a bunch of times.

That list sounds like nothing. It was the slowest part of the day. Every blocker in the last stretch was paperwork only the account holder can touch, and each one failed silently first. The paywall spun forever on "Loading plans" and the fix was not code, it was an unsigned agreement buried in App Store Connect.

Real devices find real bugs

The simulator run was clean. The first sixty seconds on my actual phone found a bug: the keyboard covered the tab bar and there was no way to dismiss it, so you could get trapped on the chat screen before ever signing in. No scripted test would have caught it because no script taps the text field first out of curiosity.

TestFlight also taught me a rule I now know by heart. In-app purchases will not load in a TestFlight build until they reach "Ready to Submit" status, which requires a review screenshot, which nothing in the flow tells you. Xcode's local sandbox is more forgiving, which makes it worse, because everything works on your Mac and silently returns nothing on your phone.

Four builds shipped to TestFlight on day one. Build 1 proved the pipeline. Build 4 went to my family.

It charged me money and I was thrilled

The moment the day was building toward: I bought my own subscription with a sandbox account, and the server's little admin dashboard ticked from pro_users: 0 to pro_users: 1.

That number traveled a long way. StoreKit produced a signed receipt, the app sent it to the server, the server verified the signature chain against Apple's root certificate, checked the product and expiry, and flipped my quota from 15 messages to a thousand. Every link in that chain got built and verified in the same day. I stared at that 1 for a while.

The beta already caught its first bug

The plan was to end this post at my gym this morning, chest press first, same machine the original post started on. It is the 4th of July and the gym is closed. The app got tested anyway.

The night it shipped I logged a rock climbing session by voice, 30 minutes on a medium wall, and the coach handled a sport I never designed for. This morning my family joined the beta, and the first tester got stuck inside five minutes: she couldn't find any way to sign up, because sign-up only existed on one onboarding page she had swiped past. So Claude and I moved account creation onto the coach screen itself, and build 5 was on her phone before lunch. Observation to fixed build in about 45 minutes. That loop is the actual product of yesterday.

You can test it

The beta is open.

Join the Spotter beta on TestFlight — iPhone, free, first 100 testers.

Free to try, 15 coach messages a month on the house, manual logging free forever. It is two days old and the icon is a barbell Claude drew with Python, so calibrate expectations accordingly. I want to know where it confuses you. Whatever you find goes in the same feedback log Audrey's bug went in, and the fix ships the same way.

And yes, same disclosure as always: I build the tools I write about. BlackOps is mine, Spotter is mine, and the blog post Claude read to build the app was written in the same system it grew out of.

The original system is still the custom option

Spotter is the zero-setup version. The system it grew out of is still running and the original post documents all of it: the folder structure, the skill instructions, the Apple Watch step.

That version runs on BlackOps connected to my Obsidian vault, and that is exactly who it is for. Your workout history lives as markdown files you own, in your own notes, next to everything else you track. You can point any agent at it, add fields Spotter will never have, log sports I never thought of, and wire the data into whatever else your vault does. It takes an afternoon to set up instead of a tap, and in exchange you can bend every part of it.

Tap-and-go, get Spotter. Your data in Obsidian and a system you can rewire, start with the original post and BlackOps. I use both now: Spotter at the gym, the vault for everything downstream.

Built by me. For people like me.

This whole post lives inside BlackOps.

Research. Write. Publish to your custom domain. Schedule X, LinkedIn, and Threads. Send the newsletter. Generate the video. All from one Claude conversation. No tab-switching. No CMS dashboard. No copy-paste.

A content operating system for people who write.

I wrote this post inside BlackOps, my content operating system for thinking, drafting, and refining ideas — with AI assistance.

If you want the behind-the-scenes updates and weekly insights, subscribe to the newsletter.

Related Posts