How I Ship iOS Features With an Agent Team
A good prompt gets you working code. It doesn't get you the review you forgot to ask for - the reconnect that never refreshes the token, the buffer with no limit, the test nobody wrote.
So I stopped polishing prompts and started handing work to a team. Mobile Engineering Agents is a toolkit I keep in every iOS project: 14 expert roles, eight review checklists, and a table that decides which of them touch a ticket. Here's one ticket, start to finish - the live order book in NextOutcome.
I ask for the outcome, not the files
Setup is a clone and one line:
git clone https://github.com/sokpichdev/mobile-engineering-agents.git .mobile-agents
echo "@.mobile-agents/CLAUDE.md" > CLAUDE.mdThen I say what I want, the way I'd say it to a person:
Add a live order book for a market. It has to survive the connection dropping.No file list, no "read this first". Every session opens with one line -
Mobile Engineering Agents — loaded ✓. If it's there, I'm wired in. If it isn't, I fix that
before I read another word, because a half-loaded toolkit still sounds confident.
The table picks the team
My sentence is a realtime feature, and there's a row for that:
| Request | Starts with | Then |
|---|---|---|
| Realtime feature | WebSocket Expert | Architect → WebSocket → Security → Testing → Reviewer |
| Auth / login / tokens | Security Expert | Architect → Security → Networking → Testing → Reviewer |
| "It's slow" | Performance Expert | Performance → specialist → Testing |
The rule behind it is short: whoever owns the thing being built goes first, everyone else reviews after.
I got this wrong at first by running the whole line every time. Five experts on a padding fix is a waste - it buries the one comment that mattered. Now small changes go straight to the specialist and a single reviewer, and only real features run the full chain.
The two I never asked for
An order book is a good example because the lazy version works. Open a socket, read the data, draw the bids and asks. It demos fine. It falls apart on a real network.
Security joins because the socket logs in, and it catches the thing everyone forgets at 11pm: a reconnect is a new connection. If the token expired while the phone was in a tunnel, reconnecting with the old one fails in a way that looks exactly like bad signal. Refresh first, then reconnect.
Testing joins because reconnecting isn't one function, it's a sequence - drop, wait, log in again, resubscribe, catch up. Every step is somewhere to be wrong, and none of it is covered by a test that checks the screen renders.
Neither was in my sentence. Both were in the row. (The Swift side of all this - actors, streams, backoff jitter - I wrote up separately.)
A checklist that can say no
Every chain ends at a checklist, and this is where most of these setups quietly fail. "Is the code good?" is not a check. It's a mood. A real check is something the work can fail:
- Reconnects with a growing delay, never a tight loop.
- Logs in again on every reconnect, refreshing the token first.
- Buffers have a limit, and a rule for what to drop when they're full.
- The screen shows when the connection is down.
- Reconnecting and decoding are covered by tests.
Each line is a yes or a no. There's no "mostly" for whether a buffer has a limit.
One rule gives it teeth: a serious finding blocks the work. Small ones can be written down and skipped, but only on purpose. Without that, a review is just suggestions stapled to code that already shipped - which is what you get when you ask an agent to check its own work and watch it agree with itself.
The checklist isn't smarter than me. It's just awake at hour six.
It's free, MIT-licensed, and doesn't touch your build: github.com/sokpichdev/mobile-engineering-agents. Works with Claude Code, Codex, Cursor, Windsurf, Gemini CLI, and Aider.