I get this question a lot from indie iOS developers: what does your day-to-day with Claude Code actually look like? The honest answer is “not as cinematic as the demos.” Here’s the actual loop.
The setup
Three windows: Xcode, a terminal running claude in the project directory, and a notes file. That’s it. No Cursor, no Aider, no agentic IDE. Plain Xcode for Swift, Claude Code for everything else.
I keep a CLAUDE.md at the project root with a 15-line cheat sheet: the architecture, the conventions, the things Claude reliably gets wrong on this codebase, and the test command. Updated every two weeks, ten minutes, never more.
The loop
Plan in a notes file before touching code
Two paragraphs. What I’m building, why, and the smallest end-to-end version that proves it. I write this without Claude. The act of writing forces me to find the load-bearing question. Half the time I find a simpler approach in the second paragraph and don’t need the first one.
Ask Claude for a plan, not code
I paste my notes into the terminal and ask: “Read the relevant files. Don’t write code yet. Tell me how you’d structure this and what I’m missing.” Nine times out of ten, the response includes one consideration I hadn’t thought of (auth refresh, edge case in the schema, a Swift concurrency gotcha).
The tenth time, the response is a bad plan and I push back. Pushing back on Claude’s first answer is the most underrated skill in this whole workflow.
Have Claude implement the smallest slice
Not the whole feature. The smallest slice that runs end-to-end and demonstrates the working principle. For a new screen, that’s the data model + a hardcoded view + the navigation hook. For a backend service, it’s the route + the simplest possible handler + a curl command that proves it works.
The slice is wrong half the time. That’s fine. It’s wrong fast, on a 50-line surface area instead of a 500-line one.
Run it, observe, decide
Build in Xcode. Tap the button. Read the output. This is the part that AI—driven workflows skip and I think they suffer for it. You have to actually run the thing. Most of the bugs Claude introduces are visible in the first 30 seconds of human interaction. None of them are visible in the diff.
Iterate in 5–15 minute increments
Each ask is small. “The login button is firing twice on slow networks.” Not “Build the login flow.” The big asks produce big diffs which are hard to review and harder to undo. The small asks produce small diffs which I can read line-by-line in 90 seconds.
The hard rules
- I read every diff. Even the ones I asked for. Especially the ones that look right.
- I run the tests after every commit. Tests are non-negotiable on a codebase one person owns.
- I do not ask Claude to write the architecture. The architecture is mine. Claude executes within it.
- I do not let Claude touch the App Store metadata, the entitlements, or the App ID config. These are the places where mistakes are expensive and silent.
- I commit at every working state. Even broken-but-stable. I want to be able to
git reset --hardwithout thinking.
The hard-won lessons
SwiftUI confuses Claude in specific ways
State management across view boundaries, environment values, and the difference between @State and @StateObject: Claude’s answers here are 70% correct, which is the worst kind of wrong. The 30% that’s subtly broken will burn you on shipping day. I review SwiftUI state changes line by line.
Async/await is fine; Combine is sometimes a trap
Claude writes good async/await code. Claude writes Combine code that compiles and does roughly what you asked, but in a way that creates retain cycles you find six months later. I avoid asking Claude to use Combine.
The Xcode project file is dangerous
If Claude touches project.pbxproj, I read every byte of the diff. The places merges go wrong are exactly the places I cannot afford merges to go wrong.
The output
CarCampro shipped to the App Store in four months. Solo. The app is 32k lines of Swift, 60% of which I wrote by hand and 40% of which Claude wrote with my review. The bugs in production track with the parts I wrote — not because Claude is better, but because the small-slice loop catches Claude’s mistakes before they ship.
The headline is the loop, not the assistant. The assistant is interchangeable. The discipline of small slices, real running, and reading every diff is what makes the thing work.