Inspiration

Every January I wrote goals into a notes app and never opened it again. The problem was never the list — it was that the list lived somewhere I had to choose to look. The one screen I look at hundreds of times a day without choosing is the Lock Screen. So the question became: what is the smallest goal tracker that fits on a wallpaper and is still fun to fill in?

A bingo card. 9, 16, or 25 squares, one goal each. Complete a row and you get a BINGO. It needs no streaks, no daily check-ins, no guilt — just a grid that slowly fills up in front of you.

What it does

  • Put your goals on a 3×3, 4×4, or 5×5 bingo card for a day, a month, a year, or any period.
  • Tap a square when it's done. Rows, columns, and diagonals light up as bingo lines, with confetti and a cheer that escalates from "first line" to "blackout".
  • Lock Screen wallpaper (iPhone): the card renders at your device's exact pixel size, and a one-time Shortcuts automation redraws the wallpaper whenever you open or close Bingoal. Your progress is on the Lock Screen without you doing anything.
  • Widgets: Home Screen (small/medium) and Lock Screen accessory widgets (circular/rectangular) on iOS; desktop widgets on Mac.
  • Native Mac app: your card in the menu bar with one-click toggling, and as the desktop wallpaper.
  • Bingoal Pro: iCloud sync between iPhone and Mac, eight wallpaper themes plus a custom palette, matching app icons, and blending one of your own photos into the wallpaper.
  • No account, no server, no analytics. Cards stay on device; sync goes through the user's own iCloud.

How we built it

  • One SwiftUI codebase, one target, iPhone + Mac (Swift 6 strict concurrency, Tuist). Same bundle ID on both platforms, so Bingoal Pro is a universal purchase.
  • Local-first data: cards are a single cards.json in an App Group container. The WidgetKit extension reads it directly and the app calls reloadAllTimelines() on every save, so widgets never lag behind.
  • Lock Screen pipeline: an App Intent (GetLockScreenWallpaperIntent) returns the rendered wallpaper as a file, and a bundled Shortcuts automation ("When Bingoal is opened or closed → Get wallpaper → Set wallpaper") does the rest. The app ships an iCloud link to the pre-built shortcut so setup is two taps.
  • Sync without a backend: CloudKit private database, a custom zone, change tokens, and a single merge rule everywhere — union by card ID, newer updatedAt wins. The same rule powers device-to-device sync links (bingoal://sync#…).
  • Monetization with RevenueCat: the "Bingoal Pro" entitlement gates sync, themes, and photo blending. On iOS the paywall is a remote RevenueCat Paywall (edited in the dashboard, no app update needed); on macOS it's a native package list built on the same offering. Anonymous RevenueCat app-user IDs plus StoreKit restore mean identity is fully Apple-managed — we never had to build accounts.
  • Landing page: Vite + React + Tailwind on Cloudflare Pages, English/Japanese, hosting the privacy policy and terms that App Review requires.

Challenges we ran into

  • iOS 26's "Set Wallpaper" action produced a black poster when the image came from an app intent (the stored layers were fine; only the composite went black). iOS 27 fixed it. We ended up shipping OS-specific setup guides: the older "Set Photo as Wallpaper" flow on iOS 26, a single automation on iOS 27.
  • Shared Shortcuts links don't serialize default toggle values. "Run Immediately" never survived sharing, so recipients got "Ask Before Running" and just a notification. The guide now makes users confirm that one toggle explicitly.
  • The lifetime product was first created as a consumable. App Store Connect can't change an IAP's type or reuse a product ID, so we re-created it as non-consumable under a new ID and re-pointed the RevenueCat entitlement and $rc_lifetime package. Caught before launch — otherwise Pro would have expired and restore wouldn't have worked.
  • Entitlement only attached to Test Store products. Sandbox purchases unlocked Pro, production wouldn't have. Fixed by attaching all three App Store products to the entitlement.

  • macOS ignores re-setting the same wallpaper URL, so the desktop wallpaper alternates between two filenames.

What we learned

  • "Always in sight" is a stronger habit lever than any notification. Once the card was on the Lock Screen, the app itself became almost optional — which is the point.
  • Not running a server is a product feature, not just a cost decision: it made "no account" honest, and it made a lifetime purchase safe to sell.
  • Set up entitlements and products through the API and verify them with a real production build before submission; the dashboard makes it easy to configure the sandbox and forget production.

What's next

  • Shared cards for couples and small teams (still via CloudKit, still no server).
  • Apple Watch complication for the "one square to bingo" moment.
  • More automation surfaces: Focus filters and a Control Center control to mark today's square.

Built With

  • app-intents
  • appkit
  • cloudkit
  • ios
  • macos
  • react
  • revenuecat
  • revenuecat-paywalls
  • shortcuts
  • storekit
  • string-catalog
  • swift
  • swift-6
  • swiftui
  • tailwindcss
  • tuist
  • typescript
  • vite
  • widgetkit
  • xcode
Share this project:

Updates

Submission history