top of page

DCC Weekly Activities: Building a 22K-Line iOS App End-to-End

  • Mar 27
  • 3 min read
DCC Weekly Activities App Icon

A case study in building a production iOS app from scratch — native Swift, serverless backend, real-time data, and 55+ features delivered through disciplined Agile practices.

The Problem

The Desi Cycling Club needed a way for members to track weekly performance, compare stats, and stay motivated. Strava shows individual rides but has no club-level weekly leaderboards, coaching insights, or comparative analytics. Members wanted to see who rode the most, track trends week-over-week, and get personalised coaching tips — all without requiring every member to share their individual Strava credentials.

The Architecture Decision

I chose native Swift/SwiftUI over cross-platform frameworks (React Native, Flutter) for three reasons: platform-native performance, direct access to Face ID and Speech Recognition APIs, and zero third-party UI dependencies. For the backend, Cloudflare Workers won over Firebase and AWS — edge-deployed, sub-100ms cached responses, generous free tier, and deploys in under 10 seconds via Wrangler CLI.

The key architectural choice was club code authentication — a shared code (DCC2026) instead of individual Strava OAuth. This keeps the app simple for members while a single bot account on the Worker fetches club data server-side. Strava secrets never touch the client binary.

DCC Weekly Activities — Club Code Login Screen on iPhone

Tech Stack

  • Swift 6 / SwiftUI — async/await concurrency, @Observable pattern, iOS 17+

  • Cloudflare Workers (JavaScript) — serverless API with KV edge caching and cron triggers

  • Strava API v3 — OAuth token proxy, club activity aggregation, sport type enrichment

  • Jira REST API — automated issue creation from in-app voice/text feature requests

  • Face ID / Touch ID — biometric authentication with iOS Keychain storage

  • Speech Recognition — on-device voice dictation (no cloud transcription)

  • Swift Charts — radar charts, scatter plots, distance bar charts

Scale & Complexity

  • 80 Swift files, ~22,000 lines of production code

  • 55+ features shipped across 12 categories, all tracked in Jira

  • 5 interactive tabs: Ride, Overview, Leaderboard, Insights, Analysis

  • iPad adaptive layout with sidebar navigation and Stage Manager support

  • Apple TV companion app (read-only club dashboard)

  • Protected Core Framework (SCRUM-56) — 3-tier file protection with 6-step change control

  • Compile-time Feature Registry — build fails if any critical type is accidentally removed

Feature Highlights

  • Weekly report table with trend arrows and week-on-week comparison

  • Interactive charts: 5-axis radar, speed vs elevation scatter, distance bars

  • AI coaching tips with What-If scenarios and gap analysis

  • Animated performance rings showing your stats vs the club

  • Ride type filter — Road, Mountain Bike, Gravel, E-Bike, Virtual

  • Voice dictation feature requests that create Jira tickets automatically

  • Offline support with disk caching and queued requests that auto-send

  • Celebration cards with confetti animations for every rider

Live Feature Dashboard

The interactive feature dashboard below is live — it pulls directly from the Jira SCRUM project via a Cloudflare Worker, auto-categorises features by status (Live, Planned, Shelved), and refreshes hourly. Search, filter, and explore all 55+ features:

Explore the live dashboard: DCC Feature Dashboard

What I Learned

The biggest lesson was that discipline scales. The Protected Core Framework — inspired by change control processes I learned in investment banking — prevented every potential regression across 55+ feature additions. The 6-step process (Impact Declaration, Audit, Proposal, Approval Gate, Implementation, Documentation) feels heavy upfront but pays for itself the first time it catches a breaking change.

The second lesson: AI-assisted development is transformative when given guardrails. A CLAUDE.md file checked into the repo encodes architecture rules, protected files, and coding standards. The AI reads it every session, producing consistent, high-quality code without accidentally restructuring critical flows. I wrote about this pattern in a separate post.

If I started over, I would modularise the Cloudflare Worker into separate files for testability, and add Durable Objects for real-time WebSocket push. But for a club-sized app, the single-file Worker approach is refreshingly simple — and it ships.

Comments


Featured Posts
Recent Posts
Archive
Search By Tags
Follow Us
  • Facebook Basic Square
  • Twitter Basic Square
  • Google+ Basic Square
bottom of page