Inspiration

I build ad SDKs for a living. I have spent years working on the machinery that turns human attention into inventory: infinite feeds, pull-to-refresh, and autoplay. I also watched that machinery eat my own evenings.

I wanted to build a focus app with the same care, but pointed in the opposite direction. Not a grey wall, a shame loop, or another streak to maintain. Pawwall uses a character you can care about, a kind pause, and numbers that belong to you. Mau — a stubborn, secretly soft cat — guards the apps you choose with Apple's Screen Time technology. When you reach for one, Pawwall creates just enough space to make the next choice deliberate.

I'm Fares, the solo developer behind Pawwall. Follow the build on X: @FaresBenhamouda.

What it does

  • Shows your time as a life, not a generic statistic. Onboarding asks about your daily screen time, habits, and age, then fills a 90-dot life grid. Screen-years and possible years won back are estimates calculated on device from your answers and labelled as estimates.
  • Hands you directly into protection. After joining, Mau greets you by name, shows your first plan as armed, and offers "Protect the next 25 minutes" for the apps you already chose.
  • Supports Focus now and recurring plans. Members can pause selected apps or categories for 15, 25, 45, or 60 minutes, or create recurring plans for parts of their day. Recommendations reflect the habits selected during onboarding.
  • Makes today legible. Home's Today card reports guarded time, reaches and times backed off, a seven-day strip, and the member's daily goal using real on-device data.
  • Turns interruption into a conscious choice. Opening a paused app presents the native system shield with orange Mau and "Stay focused." "Pause with Mau" opens Court: a breathing Mau, one breath, a short reflection, and then "I'm good" or the option to open the app for five minutes.
  • Tells the story of the week. "Your week with Mau" shows guarded hours, times backed off, the best day, each plan's record, and Quiet Score. It has honest empty states and a shareable night card, with no percentile or comparison to strangers.
  • Brings people back with Mau, not with spam (OneSignal). "Check-ins from Mau" is its own opt-in, off by default and asked at the moment of value — right after the first kept plan or finished focus. Once on, OneSignal does three things. Mau appears on the Lock Screen when a scheduled plan begins — a push-to-start Live Activity with the plan's name and the time left, even when the app is closed. Journeys react to what the person actually does: a kept plan becomes a "3 in a row?" invite the next morning, a step-back at Mau's Court after midnight becomes one morning suggestion to set a Night focus plan, two quiet days after a focus become one gentle nudge, and on day 5 of a trial a recap of the hours Mau guarded keeps the paywall's "Mau reminds you 2 days before" promise. A single "Subscription saves" Journey handles billing issues, cancelled auto-renew and lapsed members without discounts. Every message is in English, German or French, daytime-only, never sent mid-focus, and never mentions which apps someone paused.
  • Keeps reminders respectful. Plan-start alerts are local, opt-in, and off by default. A local reminder two days before an active trial ends recaps the member's actual week and explains when the trial ends; it is not scheduled when auto-renew is off.
  • Brings Mau to every relevant surface. Mau breathes, blinks, twitches an ear, and reacts to the day. The app also supports a Home Screen widget, Live Activities, and the Dynamic Island. Motion has a Reduce Motion treatment, and synthesized sounds respect the silent switch. Light, Dark, or Auto (Mau's night after 20:00).
  • Uses one honest membership. Pawwall has a hard paywall and one feature set: annual at $49.99 with a 7-day free trial for eligible customers (eligibility is checked before any trial copy is shown). A $5.99 weekly option is in App Review.

How we built it

Pawwall is a native SwiftUI app. Its focus path is offline-first so the shield, schedules, and Court do not depend on a network request.

The protection layer uses Apple's Family Controls stack end to end: FamilyControls for authorization and app selection, ManagedSettings for shields, and DeviceActivity with a DeviceActivityMonitor extension for recurring schedules. Dedicated ShieldConfiguration and ShieldAction extensions provide the custom system shield and route "Pause with Mau" into Court.

RevenueCat powers the hard paywall. The app loads the packages of the current RevenueCat offering (annual today; a weekly package is in App Review), checks introductory-offer eligibility before presenting the 7-day annual trial, restores purchases, and keeps enforcement behavior separate from purchase handling. The paywall clearly states, for eligible customers, 7 days free and then $49.99/year, and shows only the plans the App Store can actually sell.

OneSignal powers re-engagement. The app sends behaviour events — focus_completed, plan_kept, shield_backed_off, and court_visit {hour} — plus coarse tags (membership, trial_day, plans_count, will_renew, billing_issue, in_focus, streak_days, has_night_plan, hours_guarded_week). The Screen Time shield runs in an extension that cannot talk to the network, so it counts step-backs locally and the app forwards the delta on the next launch. Everything is consent-gated: OneSignal is initialised with consent required, and events, tags and the push subscription only exist while "Check-ins from Mau" is on. Five Journeys (streak, drift, morning-after, trial day-5 and subscription saves) use Wait Until, Yes/No branches, time windows and message goals, so each flow is measured rather than assumed. Live Activities: iOS won't let the Screen Time extension start a Live Activity, so the app sends only plan times (ids, weekdays, start/end, time zone, paused-app count — never names) to a small Cloudflare Worker. Every minute it checks what's starting and calls OneSignal's push-to-start Live Activity API; plans longer than 8 hours are split into back-to-back activities, and every start, update and end is sent exactly once. A contract test keeps the Worker's payload identical to the app's ActivityAttributes, and it was verified on a real iPhone with the app closed.

Firebase Crashlytics (behind the same privacy switch as analytics) and Mixpanel close the loop: crashes are symbolicated from uploaded dSYMs, and Mixpanel records the product funnel from onboarding and the life-grid moment through paywall view, purchase, welcome, and first protection. Events use a random per-install identifier and never include the identities of selected apps.

The craft layer is code-driven too. A reusable effects system handles blur-in typography, count-ups, glow, the dot grid, signature drawing, and haptics. Mau is an animated vector character driven by a dedicated animation engine. Every chime and tick is synthesized in code with AVAudioEngine; there are no bundled sound recordings.

Challenges

Building on Apple's Screen Time boundaries

Family Controls data is deliberately private and device-bound. Authorization, app tokens, shields, and the real intervention flow must be tested on a physical iPhone, while extensions have tighter execution and communication constraints than the main app. We kept extension behavior small and reliable, shared only the minimum on-device state, and made permission failures explicit instead of pretending protection is active.

Making a hard paywall feel honest

There is no free path after onboarding, so price and trial language must be exceptionally clear. Pawwall shows the real prices from the store, checks eligibility before promising a trial, provides Restore, and avoids fake scarcity, countdowns, or exit offers. Everyone who joins gets the same complete feature set.

Retention without becoming the problem

A focus app that spams notifications contradicts itself. Every OneSignal message had to earn its place: triggered by real behaviour, sent in daylight, once per trigger, measured by a goal, and only ever for people who explicitly said yes.

Making interruption calm instead of punitive

A shield must stop an automatic gesture without starting a shame spiral. The shield gives one clear way back to the day and one path into Court. Court slows the moment down with a breathing Mau, one breath, and a small choice. Sounds, haptics, color, and motion support that pause while honoring the silent switch and Reduce Motion.

Accomplishments we're proud of

  • The complete physical-device loop works: choose apps, arm a plan, encounter the native shield, enter Court, and either back off or intentionally continue for five minutes.
  • The post-purchase welcome does useful work. It preserves the member's onboarding selection and starts the first 25-minute protection in one tap instead of dropping them on an empty dashboard.
  • Home and "Your week with Mau" turn private device data into a readable story without social proof or surveillance mechanics.
  • A behaviour-driven OneSignal lifecycle (streak, drift, morning-after, trial day-5, subscription saves) plus push-to-start Live Activities, all in three languages and respecting Screen Time privacy end to end.
  • Mau feels consistent across onboarding, Home, the shield, Court, widgets, and live surfaces, with animation and synthesized sound built as reusable systems.
  • 27 builds shipped through TestFlight in two months, each one checked on a real iPhone before the next.

What's next

  • Measured proof: a DeviceActivityReport view of real minutes on the guarded apps, week over week — rendered on device, never compared against the self-reported onboarding estimate.
  • Honest projections everywhere: savings shown in years, months, or no number at all — never rounded up to a flattering "1 year".
  • Distribution: Apple Search Ads with message-matched custom product pages (sleep, focus, doomscrolling), AppsFlyer attribution for short-form video, and more languages after English, German and French, chosen from App Store search data.
  • Packaging: annual plus a $9.99 monthly option, decided on revenue per paywall view — not on a guess.

Category fit

Keep Them Coming Back Award — OneSignal

Retention in a focus app has a trap: every push is itself an interruption. Pawwall treats OneSignal as a behaviour engine, not a megaphone. Consent is explicit and separate from analytics, requested only after the person has felt the product work. Journeys are triggered by real behaviour — a kept plan, a step-back after midnight, two days without a focus, a failed payment — and each message rewards progress or removes friction instead of asking for attention. Time windows keep everything in daylight, an in_focus tag keeps Mau quiet during a session, Wait Until branches cancel a nudge the moment the person comes back on their own, and message goals (tap-through for billing, app-opens for win-back) measure whether each flow earns its place. The shield extension cannot reach the network, so step-backs are counted on device and forwarded later — the integration respects Apple's Screen Time privacy boundary end to end. The most direct way to reduce screen time is to not need the phone at all: when a plan starts, OneSignal puts Mau on the Lock Screen with the time left, so the person can see they're protected without unlocking.

RevenueCat Design Award

Pawwall treats focus as an emotional design problem. The 90-dot grid makes an abstract cost visible; the night-to-dawn transition turns realization into relief; the hand-drawn promise makes commitment physical; and the welcome converts that promise into a working protection. Mau is not decorative: they breathe, blink, react, guard the system shield, and guide the single breath in Court. Rounded type, restrained color, synthesized sound, haptics, and Reduce Motion support one coherent language from onboarding through the weekly story.

RevenueCat Peace Prize

Pawwall is digital wellbeing without an attention business hiding underneath it. There are no ads, accounts, social graph, leaderboards, or public comparisons. App selections and focus history stay on device. Analytics are coarse, omit selected-app identities, and can be disabled. The product does not punish a lapse: it asks one honest question, offers one breath, and leaves the final choice with the person.

HAMM

The monetization is legible and fully integrated into the experience: one hard paywall, one feature set, annual at $49.99 with a 7-day trial only for eligible customers (a $5.99 weekly option is in App Review). RevenueCat serves the current RevenueCat offering and handles entitlement and restoration; Mixpanel measures the path from onboarding to paywall, purchase, welcome, and first protection; OneSignal's Subscription saves Journey handles failed payments and lapsed members without discounting. The paywall uses the person's own before-and-after estimate rather than fake urgency.

Built With

  • activitykit
  • cloudflare-workers
  • family-controls
  • firebase
  • firebase-crashlytics
  • ios
  • mixpanel
  • onesignal
  • revenuecat
  • screen-time
  • storekit
  • swift
  • swiftui
  • widgetkit
Share this project:

Updates

Submission history