Solo product build · Product strategy, iOS architecture, UX design, AI-augmented dev · 2026
A voice-driven watchlist that knows which of your subscriptions already carries the show.
- Problem
- Tracking what to watch is full of friction, adding titles is fiddly, the list is hard to keep current, and nothing tells you which of the services you already pay for actually carries the show.
- Solution
- Add by voice in a sentence, manage a watchlist that stays in sync across iPhone, iPad, Watch, web, and cloud, and see at a glance which active subscription streams each title, kept fresh by scheduled scraping.
- Stack
- SwiftUI, SwiftData with CloudKit sync, TMDB v4, and App Intents for Siri, backed by an engineering-grade caching layer and scheduled cron jobs that scrape streaming availability across multiple sources.
Manage a personal TV and movie watchlist by voice. See at a glance which of your active streaming subscriptions carries each title. Track season counts. All in an adaptive table that works across iPhone and iPad. SwiftUI, SwiftData with CloudKit sync, TMDB v4, and App Intents for Siri, designed, architected, and built in a single focused session, with cross-device CloudKit sync verified on real hardware.

Friction is the enemy
A watchlist only works if keeping it current costs nothing. Adding a title shouldn't mean opening the app, searching, tapping through screens. Saying "add Severance to my watchlist" to Siri and having it appear, correctly matched against TMDB, is the difference between a list people maintain and a list people abandon. App Intents make the add path a single spoken sentence from anywhere on the device. The list itself has to stay just as effortless once titles are in it. Marking something watched, tracking how many seasons deep you are, filtering down to what's actually available tonight, none of it should require thought. The watchlist is an adaptive table that reshapes itself from iPhone to iPad, with the same low-friction interactions whether you're talking to it or tapping.
Knowing where to watch
The feature that earns its keep is the one that answers "do I already pay for this?" For every title, WatchlistPro shows which of the user's active subscriptions carries it. That answer is only useful if it's current, and streaming availability changes constantly as licensing deals come and go. Keeping it accurate is an engineering problem, not a UI one. The solution is a caching layer fed by scheduled cron jobs that scrape availability across multiple sources, so the app reads fresh, pre-resolved data instead of hammering APIs at launch. The same resolved availability flows across surfaces, iPhone, iPad, Watch, web, and cloud, so the answer is consistent everywhere the user checks. The mindset behind it is an engineer's, cache aggressively, schedule the expensive work, and serve the user something fast and correct.
CloudKit-correct from line one
SwiftData's CloudKit backend is unforgiving in ways that don't show up at compile time. It silently refuses to sync if any stored property lacks a default value, if any unique-attribute constraint exists, or if the container doesn't degrade gracefully when no iCloud account is present. These are runtime failures, discovered in production unless you know to prevent them. The work was knowing the full constraint set before the first model was written, so the data layer was correct from the start rather than debugged after a crash.
The debugging that mattered
The most time-consuming debugging had nothing to do with business logic. Building against the Xcode 26 SDK while targeting iOS 17 surfaced an undocumented change in how SwiftUI's ForEach resolves its overloads, causing integer-range loops inside certain views to bind to the wrong initializer. No Stack Overflow thread. No release note. The fix came from reading compiler errors, forming a hypothesis about overload preference, and restructuring the views to bypass the ambiguous context. That is a debugging skill, not a prompting skill.
The visual language for streaming services was designed as a type system. StreamingService is an enum with computed brand color, display name, and provider ID. Adding a service means adding one case. The entire UI updates. Design encoded as architecture.
Outcomes
A production-quality iOS app with CloudKit sync, Siri integration via App Intents, and live TMDB data. A three-tier container initialization that preserves launch reliability across simulator, device without iCloud, and device with iCloud. A streaming-service type system where the data layer, badges, and filters all derive from a single enum. XcodeGen as the project source of truth, making the structure reproducible and reviewable in a diff. xcconfig-based secrets management keeping the API token out of source control entirely.
Next case study
Hampton Inn / American Express
yourHamptonTag.com
