Skip to content
← All guides Product

Case Study: Building Launchcast, a Space Launch Tracker

A swiftui app case study on building Launchcast — real-time space launch data, live countdowns, and native iOS architecture decisions explained.

Case Study: Building Launchcast, a Space Launch Tracker

Space launch tracking sounds niche — until you realise there are millions of people who set alarms for Falcon 9 launches. Launchcast started as an itch we wanted to scratch ourselves and turned into one of the sharpest real-time data products we have shipped. This swiftui app case study walks through the decisions that shaped it: API strategy, live countdown mechanics, widget engineering, and the architecture choices that kept the codebase lean as feature scope grew.

If you are evaluating what a well-built SwiftUI app looks like in practice — or you are a startup planning a data-driven iOS product — this breakdown is for you.

The Problem: Space Launch Data is Messy

The global launch calendar is fragmented. Different agencies (NASA, SpaceX, Roscosmos, ISRO, JAXA) publish schedule changes on different cadences, sometimes with hours of notice. A great tracker has to:

  • Surface the next 10–20 launches in a prioritised, scannable list
  • Update countdowns in real time without hammering the battery
  • Handle “NET” (No Earlier Than) times gracefully — launches slip constantly
  • Send a push notification at T-24h, T-1h, and a “go for launch” alert
  • Work offline for cached data while staying fresh when connectivity returns

None of this is trivial. Let us go through each piece.

API Architecture: The Right Data Source Matters

We integrated with the The Space Devs Launch Library 2 API — the most comprehensive public space launch dataset available, covering 50+ launch providers with rich metadata (pad location, mission description, crew manifests, livestream URLs).

The key architectural decision was two-tier caching:

  1. URLCache + ETag — for list endpoints that change infrequently, we respect the ETag header and skip re-parsing unchanged payloads.
  2. SwiftData persistence — detailed launch records are stored locally so the app opens instantly and functions offline.

A background URLSessionConfiguration with .discretionary = false and a small fetch interval keeps data fresh without waking the app unnecessarily.

Lesson: For data-heavy apps, the difference between a fast, reliable experience and a slow, battery-draining one is almost always in the caching layer — not in the UI code.

SwiftUI Architecture Choices

This is where the swiftui app case study detail gets genuinely useful. We followed the MVVM pattern we use across all our iOS projects, with one addition: a LaunchRepository layer sitting between the ViewModels and the network/persistence layer.

// LaunchRepository is the single source of truth
@Observable
final class LaunchRepository {
    private(set) var upcomingLaunches: [Launch] = []
    private(set) var isFetching: Bool = false

    func refresh() async { ... }
    func launch(id: String) -> Launch? { ... }
}

ViewModels hold a reference to LaunchRepository (injected via the environment), subscribe to state changes reactively, and transform data for the specific screen. This means the LaunchDetailViewModel and LaunchListViewModel never duplicate network logic.

Live Countdown: The Clock Problem

A ticking countdown sounds trivial. The naive approach — a Timer firing every second updating @State — causes full view re-renders every second across every visible launch cell. On a list of 20 launches, that is 20 × 60 = 1,200 unnecessary renders per minute.

Our solution: a single CountdownClock observable that publishes a Date (current time) every second. Each cell computes the display string inline from launch.net - clock.now. SwiftUI diffing detects only the changed string per cell. Battery impact dropped measurably.

Home Screen Widgets with WidgetKit

The widget was one of the most-requested features before launch. We shipped three widget sizes:

SizeContent
SmallNext launch name + countdown
MediumNext launch + agency logo + pad location
LargeTop 3 launches with mission summaries

WidgetKit forces a fundamentally different mental model: there is no live data; you provide a Timeline of TimelineEntry snapshots. For countdowns, we generate entries at key intervals (every 10 minutes, then every minute inside T-1h) and let TimelineReloadPolicy.after(_:) handle refresh cadence. This delivers a countdown that feels live while consuming almost no CPU.

Push Notifications and Scheduling

Launchcast uses remote push notifications for launch alerts, not local notifications, because launch times change. If a launch slips 2 hours and you have already scheduled a local UNNotificationRequest for T-1h, the user gets an incorrect alert.

The architecture:

  • App registers for push and sends the deviceToken to our Supabase backend.
  • A scheduled Edge Function polls the Launch Library API, diffs the upcoming launches against stored state, cancels outdated notifications, and sends new ones via APNs.
  • Notification payload includes a launch_id so the app deep-links directly to the correct detail screen on tap.

This approach means notification accuracy degrades gracefully — if our backend is slow, the user simply does not get an early alert, which is better than a wrong one.

Design: Information Density Without Clutter

Space enthusiasts want data. We resisted the temptation to hide details behind multiple taps. The launch list card surfaces:

  • Mission name and vehicle (e.g. Falcon 9 Block 5)
  • Agency flag / patch
  • Countdown badge (colour-coded: green for confirmed, amber for NET, red for hold)
  • Pad location

The detail screen adds orbit type, crew manifest, payload mass, and an embedded livestream link. Dark mode was designed first — space apps belong in the dark.

We used SF Symbols throughout for consistency and accessibility. Dynamic Type support was non-negotiable; a detail-rich app is useless if the text is unreadable on the largest accessibility sizes.

What the Build Actually Cost

For context, here is how a project like Launchcast fits into our typical scope brackets:

ScopeTimelineCost Range
Simple tracker (list + detail, no widgets)2–3 months$15–30k
Launchcast-equivalent (widgets, push, caching, SwiftData)4–6 months$35–55k
Full platform (iOS + backend + web dashboard)7–10 months$60–100k+

Launchcast sits squarely in the middle bracket. Most of the complexity budget went to the notification backend, WidgetKit timeline logic, and the offline-first caching architecture — not the UI.

Lessons We are Taking to Future Projects

  1. Own your data pipeline. Relying on a third-party API for real-time features means building a thin synchronisation layer you fully control.
  2. WidgetKit is worth the investment. Widget adoption drives retention. Users who pin a widget open the app significantly more often.
  3. Observability matters at launch. We instrumented every API call and widget refresh with lightweight logging piped to Supabase. Knowing exactly where errors occur in production is worth the setup time.
  4. Content is a feature. The mission descriptions and crew bios in Launchcast came from the API but we curated their display carefully. Raw data does not equal a good product.

What You Can Take From This

If you are building a data-driven iOS product — a sports tracker, a finance dashboard, a health monitor — the patterns above apply directly:

  • Two-tier caching prevents cold-start latency and saves bandwidth.
  • A repository layer between ViewModels and data sources keeps code testable and replaceable.
  • WidgetKit timelines are not hard once you understand the snapshot model.
  • Server-side notification management beats local scheduling for time-sensitive alerts.

You can see Launchcast and our other shipped products on the work page. If your product needs the same care in architecture and craft, we would love to hear about it.


Building a swiftui app that handles real-time data, widgets, and push notifications well requires deliberate architectural choices at every layer — we have made those mistakes so you do not have to. Reach out via the contact form and let us scope your project.

Building something like this?

Fera Tech ships iOS & full-stack apps end-to-end. Tell us about your project.

Start a project
Call us Open business Telegram