Inspiration

Every parent-facing feature we'd shipped before this project ran into the same wall: apps that only report screen time don't actually change behavior, and app-level blockers that live outside iOS's own permission model are trivially uninstalled or worked around by a determined ten-year-old. We wanted to build something that used Apple's real Screen Time and Family Controls framework to enforce limits — not just nag about them — and that felt as reliable to a parent as a lock on a door, not a suggestion.

What it does

ScreenFree lets a parent pair their child's device and set daily app entry limits and schedules — including "block everything" windows — that are enforced directly at the OS level via Apple's Family Controls and DeviceActivity APIs. Changes take effect immediately (no separate "Apply" step), parents get pushed a heads-up if a child's device goes out of compliance, and the whole experience is gated behind a proper account and PIN so only a parent can change or remove restrictions.

How we built it

The client is a native SwiftUI iOS app split across an app target and several extensions (a DeviceActivity monitor extension for enforcement that runs even when the app isn't open, a Notification Service Extension for push, a location-push extension), with SwiftData for local caching and versioned schema migrations. The backend is a FastAPI service on Cloud SQL that owns family/device state and a config-version counter so client and server enforcement never drift apart; Firebase handles auth, RevenueCat handles subscriptions, and Singular handles attribution. We localized into English, Spanish (Mexico), and Portuguese (Brazil) — including the strings inside Apple's own system permission dialogs, which live outside the normal localization file and get missed by most apps. Throughout, we paired hands-on iOS engineering with an AI coding collaborator (Claude) for specs, planning docs, and diagnosing some of the trickier bugs below before we touched code.

Challenges we ran into

Enforcing restrictions at the OS level turned out to be full of races most report-only apps never hit. Deleting a schedule mid-window could leave apps shielded for a moment because the DeviceActivity extension recomputed its plan before our own save had landed. Push notifications silently stopped working for any child device that was removed and re-paired on the same phone, traced back to a token store living in per-process storage instead of the shared App Group all our extensions actually run in. On the billing side, a RevenueCat customer can accumulate multiple App User IDs once they've ever been anonymous, and matching webhooks on the wrong one desynced subscription state from what the parent had actually paid for. iOS 26 also changed Apple's own Screen Time authorization flow mid-project, replacing the classic parental-approval sheet with a new device-passcode flow, which forced an entitlements rework across every App ID. And App Store submission was its own gauntlet — an icon rejected over a single imperceptible point of alpha, a location-push entitlement that only turned out to be required once we hit real validation, and an automated review scan that flagged an entitlement we could prove was already there. On top of the product work, we also had to solve a very hackathon-specific problem: giving judges a way to reach the full paid experience without a shared login or public promo codes, which we did with a hidden, server-gated toggle we can flip from our own tooling without resubmitting a build.

Accomplishments that we're proud of

Getting from a blank repo to real, OS-enforced restrictions live on the App Store in about five weeks feels like the biggest win — especially because "real enforcement" is a much harder bar to clear than "screen time report." We're proud of catching and fixing several device/extension race conditions through actual on-device testing rather than assuming the happy path, of localizing three languages deeply enough to cover system dialogs most teams never touch, and of listening to early demo feedback closely enough to cut an entire "Apply" step out of the product because parents expected Save to just mean in effect.

What we learned

Screen Time enforcement on iOS is a genuinely distributed system — state is split across the main app, multiple extensions, App Group storage, and a server config version, and the gnarliest bugs live at the seams between those, not inside any single component. We also learned to design deliberately for the messy real world: offline launches, killed processes, and devices re-paired after a teardown all need their own recovery paths, or a parent ends up stuck with no way forward but a reinstall. And building for a hackathon taught us that installability matters as much as feature count — designing so a judge can go from download to the real, full experience in minutes changed some of our technical decisions along the way.

What's next for ScreenFree

Next up is broadening enforcement coverage (deeper tamper-alert detection beyond the current phase 1, and the device-ownership-transfer flow already spec'd for parents handing a phone down to a sibling), expanding past our first three languages, and continuing to close the gap between "the parent changed a setting" and "the child's device reflects it" to zero latency, everywhere.

Built With

  • apple-screen-time-api
  • deviceactivity
  • docker
  • familycontrols
  • fastapi
  • firebase-analytics
  • firebase-auth
  • firebase-crashlytics
  • gitlab-ci
  • google-cloud-run
  • ios
  • managedsettings
  • python
  • revenuecat
  • sign-in-with-apple
  • singular
  • sqlalchemy
  • storekit-2
  • swift
  • swift-data
  • swiftui
  • terraform
Share this project:

Updates

Submission history