Building a workflow around AI
Building iOS apps brings a particular kind of satisfaction. Native rendering, Apple frameworks, the moment a feature ships to the App Store... nothing else feels quite like it.
But once I started bringing AI into my process, one thing became obvious fast: having an LLM that can write code is one thing. Having a structured workflow around that tool is another.
For weeks, I looked for the right balance. How do you keep code clean while moving faster? How do you stay in control of the architecture? How do you stop AI from going off the rails in a production codebase?
Here is the system I ended up with. It is not a theoretical tutorial: it is what I do daily on Keepio, my iOS productivity app with real users.
Isolating each task with worktrees
Every feature, fix, or refactor starts the same way: a git worktree.
git worktree add ../keepio-my-feature feature/my-featureA worktree creates a separate working copy of the repo on its own branch. While I work on a feature, the main branch stays untouched. If the experiment goes sideways, I just delete the worktree like nothing happened.
My rule: one branch, one responsibility. Feature, fix, refactor: each branch has a single goal. It is clean, isolated, and it makes code reviews dramatically easier.
When I open Claude Code in that worktree, it lands automatically in the right context and only sees the files for that branch.
Thinking before writing code
Before a single line of code, I talk with Claude. The same way I would with a colleague.
I describe what I want to build, the functional context, the constraints. He goes into plan mode: explores the existing code, analyses the architecture, and proposes an approach.
He does not decide. He proposes, I approve. Sometimes I agree, sometimes I redirect him. The point is to be aligned before touching the code.
What makes this possible is the CLAUDE.md file at the project root. It is Claude's onboarding doc: full architecture, patterns, naming conventions, project rules. Without that file, he codes blind. With it, he respects my conventions.
My CLAUDE.md contains:
- Commands for build/test/lint
- Architecture of the project (namespaces, ViewModel patterns, data flow)
- SwiftData data models
- A strict template for every View file
- Rules for navigation and premium gating
It is the highest-ROI investment I have made. One hour of writing that saves days of corrections.
Pair programming in practice
This is where it gets interesting. Claude writes the code, and I read everything in real time.
This is not "generate everything and copy-paste". It is pair programming. I am there, watching, stepping in when needed. When he proposes something that does not fit Keepio's architecture, I correct him on the spot. He gets it and adapts for the rest.
The domain expertise is mine. Claude brings execution speed. That combination is what makes the workflow work.
I also built specialised iOS plugins for Claude Code: architecture analysis, security, performance. They let me validate an approach before even starting to code.
Testing rigorously
The code is there. Before any commit, we test.
First, I ask Claude to generate a manual test checklist: everything that needs to be checked in the simulator. Why manual? Because Claude cannot launch the simulator. Anything visual, interactive, or edge-case in the UX, I check it myself.
Then we iterate until the feature behaves the way I had imagined.
Commit, SwiftLint and Push
Favourite moment: the commit.
git commit -m "feat: my new feature"The pre-commit hook kicks in. It is a script that runs SwiftLint automatically on every staged file. If SwiftLint flags violations, the commit is rejected. End of story.
Even Claude gets blocked by the pipeline. No free passes.
The script is simple but effective: it picks up staged .swift files (excluding deleted ones) and runs swiftlint lint --strict on each. A single violation, an exit 1, and the commit does not go through.
Then git push and the feature lands on GitHub, ready for review.
The big picture
Isolated worktree -> Thinking with Claude -> Pair programming -> Tests -> SwiftLint -> Push
Even without a full CI at this stage, the workflow is already solid. The worktree isolates the feature. Plan mode structures the thinking. The code is reviewed in real time. Tests are there. And the pre-commit hook bans non-compliant code from shipping.

Commentaires
Aucun commentaire pour le moment. Sois le premier !