A Reason to Stop
A curated guide to worthwhile stops across London, with true mixed-mode routing (walk, tube and bus in one route) and in-app navigation.
compiled by @Ashik
- Client
- Personal product
- Year
- 2026
- Role
- Solo Designer & Engineer
- Scope
- iOS Engineering, Product Design, Compliance
- Skills
- Native SwiftUI, Agentic workflows, App Store compliance, Systems thinking, Vibe coding
The short version
Problem. Maps show what is nearby, not what is worth seeing, and force one transport mode for a whole journey.
Action. Designed and rebuilt it solo: a hard curated-versus-generic split, fare-aware routing that mixes walking, tube and bus in one route, and in-app navigation, all in native SwiftUI with parallel coding agents.
Result. A live App Store app with 500+ curated places, rebuilt in five days with 279 commits, and no lost accounts or saved journeys.
The impact
- 500+ personally curated places
- Mixed-mode walk, tube and bus in one route
- 5 days to a full native rewrite, 279 commits
The A Reason to Stop map on iPhone, with curated places shown as photo pins around the current location.
The problem, and where I actually felt it
I spent a week in London on foot and by public transport, walking and riding everywhere, clocking 30 to 35 thousand steps a day for seven or eight days straight, trying to see as much of the city as I could. When I got back and started scrolling Instagram, I kept running into reels of places I'd never found, some of them a single turn away from routes I'd actually walked. I was right there. I just never knew to look.
Digging into why, it came down to two real gaps, not one:
Maps show proximity, not worth. Google Maps and Apple Maps are excellent at "what's near me," and genuinely bad at "what's actually worth going out of my way for." There's no layer that separates a place worth a detour from the hundred generic listings around it.
No app combines transport modes into one route. Both Google and Apple Maps make you pick a single mode, walking, or transit, or driving, for the whole journey. Neither lets you say: walk this leg because it's close, take the tube for this stretch, then a short bus, then walk the last five minutes. Real journeys are rarely one mode start to finish, but the tools force you to plan as if they are, and to jump between apps to actually execute a mixed route.
The correction: this was never actually an offline problem
The first version of this app, shipped as Foot & Line, was built around a real, well-researched constraint: large parts of the London Underground have no signal, so the app was architected offline-first from the ground up. That engineering work was sound, and the reasoning behind it held up.
But it was solving the wrong problem to lead with. The thing that actually cost me those missed places wasn't connectivity, it was never knowing they existed and never having a way to route to them efficiently even if I had. A Reason to Stop corrects the problem statement itself, not just the technology underneath it. The offline-capable architecture from v1 carries forward as a real strength, but it's infrastructure now, not the headline.
The solution
A Reason to Stop combines what Apple Maps, Google Maps, Citymapper, and TfL each do separately into one thing built for exploring on your own terms, not following someone else's pre-made itinerary.
Curated vs. Generic is a hard split, not a convenience toggle. Curated means a personally verified library, 500-plus places and growing; Generic means plain Apple Maps results with zero editorial treatment. The gap between the two tiers is deliberately visible, narrow it and the reason to have a curated tier at all disappears. This is the direct fix for the "worth seeing" problem: an always-on, see-everything map felt like just another itinerary app in the first version, on-demand curated discovery replaced it.
A phone showing the detail sheet for Borough Market, marked Curated. Curated: a personally verified place with its own detail page.
A phone showing the detail sheet for The Monument, a plain Apple Maps landmark result with no Curated badge. Generic: a plain Apple Maps result with no editorial layer.
Fare-aware, mode-mixing routing, built around how journeys actually work. Detours are offered on legs that share TfL's flat, tap-in-only Hopper fare (walking, bus, tram), since interrupting one has no fare consequence. Tube, DLR, Overground, and rail get after-arrival suggestions instead, since breaking one of those risks turning a single fare into two. This is the direct fix for the mixed-mode problem: the app reasons about your route the way you'd actually want to move through a city, not as three separate single-mode trips you have to plan and stitch together yourself.
A planned route on two iPhones: a direct route beside a curated route in light mode, and the step-by-step journey in dark mode.
In-app navigation, start to finish. Once a mixed-mode route is planned, you never leave the app to execute it.
Weather-aware suggestions and honest cost framing. A curated detour that costs more is shown as "this costs more, here's what you get for it," never as a savings claim, because a savings claim that's ever wrong once undermines the trust the whole app depends on.
Right now this is London-only. The plan is to expand to other walkable, public-transport-strong cities next, the same discovery-plus-mixed-mode-routing model, applied wherever the underlying transit and walking infrastructure supports it.
Step through the app
- A library worth going out of your way for Curated means a personally verified library, 500-plus places and growing, shown as photo pins around you. Generic means plain Apple Maps results with no editorial treatment, and the gap between the two is deliberately visible.
- Fare-aware, honestly framed Detours are offered only on legs that share TfL's flat Hopper fare, so a curated route can take longer without costing more: here it is £1.75 either way. When a detour does cost more, it is shown as what you get for it, never as a saving.
- Walk, tube and bus in one route Mixed-mode routing stitches the modes into a single journey, and in-app navigation takes you through it step by step, so you never leave the app to follow it.
- Native, down to the materials Rebuilt in five days as 100% native Swift and SwiftUI, using Apple's real Liquid Glass system materials for search, weather and filters, not custom chrome imitating them.
How it was rebuilt: from React Native to fully native, in five days
Once the real problem was reframed, the brief for the rebuild set hard constraints from day one: 100% native Swift and SwiftUI, real Apple Liquid Glass system materials throughout, not custom chrome imitating them, no shared code with any other platform. The old Foot & Line codebase was kept only as reference for its already-validated API calls, with an explicit instruction not to port from it.
What carried over deliberately: the same Supabase backend, same bundle identifier, same App Store listing, same live database schema. The rewrite shipped as a normal App Store update, existing users moved to it without losing an account or a saved journey.
Parallel agents, not one thread of work. 279 commits and 40+ merged branches in five days came from multiple autonomous coding agents running concurrently, each in its own isolated git worktree with its own booted simulator, each fully building, testing, and self-verifying a feature before it was ever merged. Only after an agent's own tests passed did the full 1,800-plus test suite get re-run clean before the next merge.
This needed real operational discipline:
| Problem hit | Fix |
|---|---|
| Hit account-level rate limits running 9 agents at once | Capped to 5 concurrent agents |
| 8 simultaneous simulators pushed disk to 94 to 100% full | Capped concurrent simulators, swept derived-data after each run |
| ~44 stale merged worktrees and branches accumulated | Cleaned up in one pass, recovered 20GB+ |
One lesson recurs in the project's own working notes: agents cannot see the UI, and a green test suite is not the same as a correct app. Several real, user-visible bugs were only caught by someone actually driving a simulator and looking.
Compliance read directly from source, before it became a rejection. Apple's Developer Program License Agreement, TfL's open licence terms, and Apple's guidance EULA requirement were each read directly rather than assumed. Apple-sourced map data is never cached long-term, in-app turn-by-turn guidance shipped behind a feature flag, off by default, pending Apple's required risk-notice work, and a missing TfL credit line was found and fixed before it could become an App Review rejection.
Two bugs investigated hard and shipped honestly unresolved. A Liquid Glass rendering glitch, real-device-only, never once reproduced in the simulator across five rounds of attempts, was fully reverted rather than ship a worse-looking, non-working fix. A biomechanically-grounded onboarding animation hit a real conflict between changing on-screen scale and a foot-plant calculation; round six found the actual root cause, built a fix, verified it numerically, then rejected it because it broke a more important guarantee elsewhere in the sequence. Net shipped change: zero, plus frame-by-frame captures left behind for whoever picks it up next.
The map in dark mode with translucent Liquid Glass panels for search, weather and filters.
Where it stands
Live on the App Store. Existing Foot & Line users received it as a normal update, same bundle identifier, same account, same backend, an entirely rebuilt app and a corrected problem statement underneath.
At a glance
- The problem
- Google and Apple Maps show what's nearby, not what's worth seeing, and force you to pick one transport mode for an entire journey
- The fix
- 500+ personally curated spots, true mixed-mode routing (walk, tube, and bus combined in one route), and in-app navigation, no switching apps mid-journey
- Cities
- London today, expanding to other walkable, transit-rich cities next
- Status
- Live on the App Store, as an update to the app formerly known as Foot & Line
- The rebuild
- Full native Swift and SwiftUI rewrite, 5 days, 279 commits, 40+ parallel agent-built feature branches