Reeler: the specswift-6.4/ios-26
Lesson 1 / 6
Unit 24 · Reeler

Reeler: the spec

Note

Unit 24 · Project 4 (Reeler, a Letterboxd clone). This is the first project on the Pair rung of the AI-usage ladder, and the first with an AI checkpoint — a milestone where you review Claude-produced code for a seeded flaw. Read this spec before writing any code.

Reeler is a film-logging app: search a film database, open a film's page, and keep your own record of it — a star rating, a like, a watchlist, a review, and a diary of what you've watched — with a profile that totals it all up. It's the personal half of Letterboxd: the social graph (following, an activity feed of other people) is deliberately later, higher-tier work. You build it to lock in the list-detail spine and a real SwiftData model where several screens are just filtered views of one store.

What you are building

  • Search — a debounced search field, a results list, and empty / loading / error states, into a film detail page (poster, director, genres, runtime, overview).
  • Log a film — from the detail page: a tappable star rating (half-stars), like, watchlist, mark watched, and a review — all persisted.
  • Diary — your watched films in reverse-chronological order, with rating and date.
  • Watchlist — the films you want to see, as a poster grid.
  • Profile — stats (films watched, this year, likes, average rating) and your lists.

What it looks like finished

Reeler film detail — poster, director, genres, star rating, like/watchlist/watched, and a review Reeler diary — logged films with rating and date, reverse-chronological Reeler watchlist — a grid of films you want to watch Reeler profile — stats and your custom lists
The finished build in the simulator: a film detail with a star rating and log actions, the diary of watched films, the watchlist grid, and the profile with stats and lists. Diary, Watchlist, and the profile stats are all filters over one persisted FilmActivity store. (Posters render as colour cards here — a real build loads them from the film API through the actor image cache.)

Concepts this project locks in

Concept Where it shows up
MVVM-lite + dependency injection SearchViewModel takes an APIClient protocol
@Observable @MainActor view model drives the search state
Debounced async search Search screen, .task(id:) + Task.sleep
Value-based NavigationStack navigationDestination(for:) with a Film value
Load-more pagination Search results append the next page
Actor-based image cache ImageLoader actor, no data races on the cache dictionary
SwiftData model + relationship @Model FilmActivity, FilmListListEntry
Views as filters over a store Diary / Watchlist / Likes are @Query filters over FilmActivity
@Bindable editing rating, like, watchlist, review write straight to the model

The AI stage: Pair

Projects 1–3 were Tutor — AI gave hints, never code. Reeler moves you to Pair: the AI may propose code, but you review and approve every diff. Nothing lands unread. This is the professional default, not a training wheel — a senior engineer reads the diff their tools produce, and the bugs that survive review are the ones nobody looked at.

Tip

The /swift-review habit. From this project on, run /swift-review on any non-trivial diff before you accept it. It checks the diff against Segue's conventions: strict concurrency, correct Sendable, @MainActor placement, capture lists, and tokens-only styling. In Pair mode the review is yours to run — the Workbench never lands a change you didn't look at.

Milestones

  1. Search + MVVM — the search screen, an injected APIClient protocol, a @MainActor @Observable view model, debounced queries.
  2. Detail + pagination — value-based navigation to a detail screen, load-more results, and an actor-based image cache.
  3. Rate, log & profile — the SwiftData FilmActivity model; the detail's rating/like/ watchlist/review; and the Diary, Watchlist, and Profile screens as filters over the store.
  4. AI checkpoint — review a Claude-produced image loader for a seeded retain cycle: find it, explain why it leaks, fix it. Then a gradable companion exercise.
  5. Rubric — self-review against the rubric and defend your design decisions.

Out of scope (on purpose)

No authentication and no server of your own (you consume a public read-only film API), and no social graph — following, an activity feed of other people, comments and likes on their reviews. That's Tier 2+ work in later projects. Reeler's job is the personal-logging spine: search, log, and the views that read back your own data. A tight scope you finish beats a broad one you abandon.

Knowledge check

Q: What changes about how you use AI on this project versus the first three? The stage moves from Tutor to Pair. AI may now propose code, but you review and approve every diff — nothing lands unread. /swift-review becomes a habit on non-trivial changes.

Q: Why are the Diary, Watchlist, and Likes not three separate stores? They're three filters over one FilmActivity store — logged, on the watchlist, liked. One source of truth means a rating you set on the detail page shows up in the diary automatically, with nothing to keep in sync.