Inherited 60,000 lines of undocumented React Native and a security vulnerability exposing every user's photos. Fixed it in week one, shipped Phase 1 inside the legacy code, then led the full native iOS rebuild — 581 Swift files, 104K LOC, 303 SwiftUI views.
The Redesign
Same product, two codebases — the legacy React Native build beside the native SwiftUI rewrite.


The Product
HornScore is a hunting app for serious hunters. Users photograph trail-cam footage, field-judge antler measurements using anatomical references, calculate official scores adapted from Boone & Crockett methodology, share scores with a community, and access species-specific guides.
The audience invests in premium equipment and expects the software to match. This is a production app with 5,000+ users.
Screens
Every flow in the production app — scoring, filters, settings, social, guides, messaging, comments, albums, reports — built from a single tokenized system. A representative selection is shown below.









What I Inherited
Before writing a single feature, I documented what was actually in the repository. Here's the report I wrote to the founders.
Every user's trail-cam photos, hunting locations, and personal images were accessible to anyone with the URL. I documented the exposure, implemented proper Firestore rules, and verified the fix before touching anything else.
Phase 1
Before proposing a rebuild, I shipped the Line Reference Tool inside the legacy React Native codebase. The goal was simple: prove that complex new functionality could be delivered in the existing code, on time, without breaking anything.
It was the work that earned the trust to propose the bigger move.

Line Reference Tool, shipped inside the legacy code.
Phase 2
First commit on the rebuild branch: November 6, 2025. Native Swift, SwiftUI, MVVM + Coordinator architecture, dependency-injection container, repository pattern, design system built to scale. Owned by one person.
Risk assessment from the shareholder progress report: technical risk LOW. The remaining work is feature implementation, not re-architecture.
The Math
The Line Reference Tool lets users place Bézier curve points on a photo and trace anatomical landmarks at up to 15× zoom — with coordinate-locked precision, even as the user pans, zooms, and re-zooms.
The trick is two bidirectional transforms between canvas space (image pixels) and screen space (the rendered SwiftUI view). Every touch event, every drawn point, every hit-test runs through these:
FieldJudgeScoringViewModel.swift — the coordinate-space math core (2,089 lines).
func screenToCanvas(_ screenPoint: CGPoint, viewSize: CGSize,
totalScale: CGFloat, totalOffset: CGSize) -> CGPoint {
let center = CGPoint(x: viewSize.width / 2, y: viewSize.height / 2)
return CGPoint(
x: (screenPoint.x - center.x - totalOffset.width) / totalScale + center.x,
y: (screenPoint.y - center.y - totalOffset.height) / totalScale + center.y
)
}↳ DetailThe Bézier rendering uses a Catmull-Rom spline with arc-length computed by parametric subdivision (200 intervals per segment), integrated in real time as the user adjusts points. Hit-testing dynamically adjusts a 44pt tap threshold to screen space, and stroke width scales inversely with zoom so lines stay visible without thickening.
The Unified Tool
The legacy app had separate straight-line and curved-line measurement modes — two interaction models the user had to keep in their head.
The rebuild collapses both into a single canvas state machine. The first two points calibrate against an anatomical reference; three or more extend into a curved measurement. The transition is automatic; users never see a mode toggle.
The code is just as direct: a seven-state enum, an auto-advancing transition function, and comments throughout marked `// Legacy — should not be entered in unified flow`.
Design System
I built the tokens first. Adaptive light/dark, semantic surfaces, a brand color that adjusts to color scheme, spring curves that match native iOS sheet snap. Every screen in the app draws from this file.
DesignSystem.swift · 586 lines
01 · Color
50+ tokens
02 · Type
20+ sizes
03 · Spacing
25 tokens · 4pt grid
DesignSystem.swift — 586 lines, dark-mode-aware throughout, used across 165 production files.
The Stack
Auth, analytics, crash reporting, subscriptions — all integrated and verified before a single feature screen was built. Standard practice in mature engineering organizations; rare in solo work.
Why this matters
If your business runs on an iPhone app that captures field data and syncs to a server, this is the same problem shape. The track record I'd bring: audit your codebase for security and architecture risk in week one, ship value inside the existing code while we plan, and only propose a rebuild when the data — not the engineer — calls for it.
william@piehsoft.com →