Milebound app icon
A native iOS app · concept to TestFlight

Milebound, built in 5 days.

A native iOS radius-alert app that tells you the moment you cross a boundary you set. It has notifications, an event log, and a map-first interface. I designed and built it solo and shipped it to real testers in under a week, and I kept going from there.

iOS 26 · SwiftUI · Liquid Glass June 10–14, 2026 Solo developer Still building · past v1
Milebound home screen, with a map, a radius circle, monitored places, and the Liquid Glass card

The real app, with live radius circles on the map, monitored places, and the Liquid Glass bottom card.

Why I built it

It started with a real need.

My husband drives long-haul trucks. He depends on a radius alert to stay within the air-mile boundary tied to his agricultural exemption, and the app he was using crashed often and hadn't been updated in years. He needed something he could actually trust on the road.

I'd been wanting to take a product all the way to shipped on iOS, so I used his problem as the vehicle. I built it in the evenings after work and on weekends, went from concept to a TestFlight build in days, and iterated through ten builds in just over a week. Native iOS was new territory, but the platform was the only new part. Turning a vague need into a clear, usable product is what I've been doing for eighteen years.

The hardest part wasn't the design, it was the system underneath it. The monitoring engine had to be built from the ground up, because the platform's standard geofencing isn't meant for distances this large. A map app that deals in distance also has to behave like the real world, so a measurement can't land in the middle of a lake where no one can walk or drive. Tracking, notifications, alerts, and the log all had to work as one coherent system instead of separate features. It also raised questions that sit above design and code, like what happens when someone declines location access, how their data is stored and kept theirs, and what fair monetization looks like for a tool like this. I worked through those myself, and used AI to research and test approaches before committing rather than guessing.

My most valuable tester turned out to be my mom. She found more bugs than everyone else combined, mostly by using the app in ways I never would have thought to design for, with her text size turned up well past anything I had tested. She broke things I would have sworn couldn't break, and kept asking why it didn't handle situations I had never considered. Chasing those down became the part I enjoyed most. Each bug was a small puzzle I hadn't seen coming, and solving it usually meant getting out of my own head and into how someone else actually used the app. That is exactly the kind of feedback you can't get from your own assumptions, and a good amount of the accessibility work, and a couple of features, exist because of her.

The visible product still had to hold a high bar, and that is where my UI and UX experience did the work: a single full-bleed map with one card instead of a tab layout, and a design system that kept everything coherent as the app grew. AI accelerated the build, but it worked inside a roadmap and a set of rules I set up to keep it disciplined. The tools are available to anyone. What they produce depends on the judgment directing them, and that came from experience.

The week at a glance

Five days to a shippable product.

The first five days, by the numbers, straight from the git history and the tester feedback log.

0
Commits
avg ~25 / day
0
TestFlight builds
in testers' hands
0
Lines of Swift
26 files · 2 targets
0
Net lines shipped
16.6k added / 2.8k cut
0
Feedback items triaged
3 real testers
0
Issues resolved
84% close rate
0
Bug & crash fixes
incl. a UIKit crash
0
Major feature systems
engine to alerts
What it does

Set a radius, get the alert.

Drop a center point and choose a radius. Milebound checks every GPS fix against every circle and alerts you the moment you cross a boundary, or approach one, with a live readout and an event log.

🎯

Long-range geofencing engine

Apple's region monitoring caps out at 20 fences and about 100 meters, so I built the engine from scratch. It evaluates radii from 0.1 to 500 miles, with an adaptive GPS mode that wakes only when a crossing is close and sleeps the rest of the time to save battery.

🔔

Unified alerts

A crossing alert on every boundary, plus up to three proximity alerts per place with inside or outside direction, each editable inline. You decide what alerts you and what just gets logged.

Overlap detection & flag-and-fix

A circle's row flags when it overlaps another, and the alerts screen catches alerts that can never trigger, like an inside alert wider than the radius, and offers the fix.

🗺️

Apple Maps-grade interface

One full-bleed map with a persistent Liquid Glass card that rests at three heights: collapsed status, half, and full. It stays interactive behind the lower detents, and there is no generic tab bar.

🧭

Land-aware distance tool

Measure boundary-to-boundary with real routing across driving, trucking, cycling and walking modes, and drag the A/B endpoints to re-measure anywhere on the map.

📅

Event log & calendar sync

Every crossing is recorded with a filterable history and CSV export, and can optionally write entries and exits straight to your calendar.

The build log

How it actually went.

The first five days took it from nothing to a build in testers' hands. The log runs to eight because I kept building after it shipped, with several days running from late morning to midnight.

Jun 10
52 commits

Zero to v1

The tracking engine, the full-bleed Maps-style UI, the Liquid Glass bottom card, map modes, settings, onboarding, calendar sync, and the rename to Milebound. It was the biggest day of the build.

Jun 11
44 commits

Polish & the first feedback rounds

A full Dynamic Type + VoiceOver accessibility pass driven by a tester's large-text screenshots, the Places/Activity list redesign, and a tricky UICollectionView crash fix.

Jun 12
5 commits

Field-report fixes

Reproduced and fixed a “dead” map button and some travel-mode confusion that testers reported, then shipped a new build.

Jun 13
2 commits

Detail card & gauge system

A rebuilt detail and measure card with boundary-to-boundary distance, on top of the shared gauge design system.

Jun 14
20 commits

Alerts and distance, Build 7

Unified Alerts screen, sub-mile radii, pin-proximity alerts, overlap detection, boundary-accurate copy, and a land-aware distance tool with movable endpoints. This shipped to testers on day five, and I kept going.

Shipped to TestFlight · Day 5. Everything below is after that.
Jun 15
26 commits

Build 8, and a website

A new app icon, a launch sequence, a permission-first onboarding rebuild, first-run map framing, and a logarithmic radius editor, plus the milebound.app marketing site, with a landing page and hosted privacy and terms, all deployed to production.

Jun 16
50 commits

Monetization, Build 9

StoreKit 2, a two-plan paywall with a “Welcome to Pro” flow, the feature-gate layer, full in-app legal docs, and the monitoring-unification work that put pins and circles under one monitor switch.

Jun 17
61 commits

Design system and widgets, Build 10

A full typography, color, and spacing token pass across every screen, home-screen widgets and a Live Activity for any monitored place, a calendar event picker for each place, and a compact status-banner system. It was the highest-commit day of the build, and I was still going.

Past the 5-day sprint

Day five was a checkpoint, not the finish.

Build 7 reached testers on day five. Three more builds followed over the next three days, adding a marketing site, monetization, a full design system, and home-screen widgets. I built all of it solo and native.

0
Days and counting
Jun 10–17, 2026
0
Total commits
avg ~33 / day
0
TestFlight builds
Build 10 prepping
0
Net lines shipped
26.8k added / 6.3k cut
💳

Monetization, done native

StoreKit 2 with an entitlement manager and a feature-gate layer behind a two-plan paywall, a free tier plus Milebound Pro, available lifetime or yearly. There are no accounts and no third-party SDK.

📲

Widgets for every place

Home-screen widgets and a Live Activity or Dynamic Island tracker that read from your monitored places, showing distance and ETA to the nearest boundary right on the Lock Screen.

🎨

A real design system

Semantic typography, a Dynamic-Type-aware color palette derived from one source, and an 8pt spacing grid, all tokenized in code and migrated across every screen in the app.

🌐

A marketing site, shipped

milebound.app is a landing page plus a hosted privacy policy and terms, built as a faithful web port of the app's design language, with SEO and a branded social card. It is live at milebound.app over HTTPS.

📅

Calendar sync, per place

Pick which places write to your calendar and exactly which events get logged, the crossings in and out plus each proximity alert, mirroring the in-app alerts as a picker.

🚀

Launch & onboarding

A SwiftUI launch sequence that dives into the map, a permission-first onboarding flow, and first-run framing that centers the user's own city before the card rises.

Engineering depth

The bugs were the hard kind.

These weren't typos. They were subtle, framework-level problems, each one root-caused and written up well enough to hand off cold.

Crash · R2

UICollectionView batch-update crash

“Invalid number of items in section” during list edits. Root cause: the store mutated synchronously inside UIKit's interactive batch update, so derived rows changed by more than the gesture. Fix: defer write-backs one runloop so SwiftUI diffs cleanly.

✓ Fixed & documented
Data loss · R1

Silent data loss on upgrade

New Zone fields made the strict JSON decoder reject older saved files outright, and one unknown field could drop a user's whole library on update. Fix: a tolerant, field-by-field decoder that preserves everything it can recognize.

✓ Hardened the decoder
Release · R1

App Store icon rejected

The marketing icon shipped as opaque art carrying a redundant alpha channel, which Apple forbids, so App Store Connect showed a blank icon. I diagnosed it from the asset metadata and flattened it to opaque RGB, pixel for pixel identical.

✓ Root-caused from metadata
Not just code

A real feedback operation.

TestFlight has no “resolved” state, so I built one: a triage standard, a system-of-record log, and risk tiers from R0 to R3. There were nineteen items from three real testers, each with a root-cause note and the exact commit that closed it.

16 Fixed 2 Needs decision 1 Deferred
0%
of triaged feedback resolved in-week
16 of 19 items · across accessibility, layout, crashes & copy
Under the hood

Native and modern.

All native, with no third-party dependencies.

SwiftUI · iOS 26 MapKit · Map, search & routing Core Location · significant-change + adaptive GPS StoreKit 2 · subscriptions & lifetime WidgetKit + ActivityKit · widgets & Live Activity EventKit · calendar sync Liquid Glass design language Design tokens · type / color / spacing system Codable persistence · split per-file writes Full accessibility · Dynamic Type + VoiceOver 0 external dependencies

From an empty repository to a working, accessible, tester-validated iOS app in five days, and three builds further by day eight, with monetization, a design system, and widgets. I built all of it solo and native.