Inspiration

Every movie night starts the same way: two people, five streaming apps and forty minutes of scrolling until someone says "fine, whatever you want". The problem isn't a lack of choices — it's too many. I wanted to turn deciding into the fun part: pull a lever, watch the reels spin, and let chance settle the argument.

What it does

The Movie Slot picks one film (or series) for you with three reels:

  • Vibe — Intense, Chill, Mind Bender, Visual Feast… each one maps to a set of TMDB keywords (Mind Bender = twist ending, nonlinear, psychological…)
  • Genre — what kind of story you're in the mood for
  • Twist — vote-count range, year limits and sort order (e.g. Hidden Gem: highly rated but rarely voted, Cult Classic, Crowd Favourite)

All three reels feed the actual TMDB query, so the result really matches what the reels landed on. Lock the reel you like and spin the rest.

The result card shows the poster, rating, runtime, director, synopsis and trailer, plus where it's streaming in your country (JustWatch data via TMDB). Save it to My List, mark it as seen, or share it as a card.

More:

  • Film of the Day — for nights you don't feel like spinning, with an "on this day, years ago" card underneath
  • Curated lists — cult classics, hidden gems, short & sweet; or spin inside your own lists
  • Lucky, a black cat with a film-strip tail, reacts to whatever the reels land on (and he dresses up for Spooky Season in October)
  • Lists sync through your own iCloud — no account, no ads, no tracking
  • iPhone and iPad, iOS 17+, localized in 7 languages (EN, TR, DE, ES, FR, IT, PT-BR)

How we built it

  • SwiftUI, native iOS/iPadOS. The reels are custom-built with a timing curve tuned so each one settles with a slot-machine "tick".
  • TMDB for film data. The API key never ships in the app: every request goes through a small Cloudflare Worker proxy, so the iOS target has zero client-side secrets.
  • iCloud key-value store for lists — no server, no sign-up. The cloud copy is slimmed down (only directors are kept from the crew list) to stay far below the 1 MB limit.
  • Lucky is a layered sprite rig driven from a JSON manifest: separate tail sprite with a pivot point so the film-strip tail can sway, a pool of poses, and seasonal costumes that only enter the pool inside their date window.
  • RevenueCat (purchases-ios) powers monetization — see below.
  • Unit tests with Swift Testing; App Store metadata and screenshots are generated by scripts and pushed through the App Store Connect API.

Monetization with RevenueCat

The app is free and has no ads — a deliberate choice, since the whole point is a calm, private movie-night tool. Instead there's a tip jar with three consumable tiers named after the cat's actual diet: Kibble ($0.99), Wet food ($2.99) and A treat ($9.99). None of them unlock features; they're a way to say thanks and keep Lucky fed.

The tip jar started on raw StoreKit 2 and was moved to RevenueCat in version 1.3. RevenueCat now handles products, purchases and finishing transactions, and a purchase interrupted halfway is recovered the next time the app opens.

Challenges we ran into

  • Catching a cancelled purchase. RevenueCat throws its errors as NSError, and as? ErrorCode silently returns nil because Swift doesn't bridge it back. Every "Cancel" tap showed up as an error until we switched to comparing the error domain and code directly.
  • "New tip" detection. CustomerInfo.nonSubscriptions carries the entire purchase history, so the first update after launch looked like a fresh tip for everyone who had ever tipped. We store the known transaction IDs once and only react to the difference.
  • Two owners of one transaction. Our old Transaction.updates listener and RevenueCat could both call finish(), so a tip could close before reaching the dashboard. The fix was to give RevenueCat sole ownership.
  • Naming a "slot" app. Words like slot machine, jackpot or roulette risk being classed as simulated gambling by App Store ads review, so the metadata and UI never use them. Slot stays only as part of the brand name.

Accomplishments that we're proud of

  • First released on the App Store on 24 August 2026, followed by three updates in under a month
  • App and store listing in 7 languages
  • No account, no ads, no tracking, and no API key in the binary
  • Lucky: a mascot with his own pose rig, seasonal wardrobe and reactions

What we learned

The picker isn't really the product; the few seconds while the reels spin are. Most of the polish went into those seconds (timing, sound, haptics, Lucky's reactions) rather than into more filters.

What's next for The Movie Slot

  • An embedded trailer player (with a YouTube fallback for age-restricted trailers)
  • Shared results that link straight to the App Store, so every share doubles as an invite
  • Clearer reel locking: a pin instead of a padlock, with haptic feedback when a locked reel is nudged
  • More seasonal collections after Spooky Season

Built With

Share this project:

Updates

Submission history