2026-09-17 17:59:34 +02:00
2026-09-17 17:59:34 +02:00
2026-09-17 17:59:34 +02:00
2026-09-17 17:59:34 +02:00
2026-09-17 17:59:34 +02:00
2026-09-17 17:59:34 +02:00
2026-09-17 17:59:34 +02:00
2026-09-17 17:59:34 +02:00
2026-09-17 17:59:34 +02:00
2026-09-17 17:59:34 +02:00
2026-09-17 17:59:34 +02:00
2026-09-17 17:59:34 +02:00
2026-09-17 17:53:51 +02:00

iOS Advanced Parental Controls

v0.1: shared family policies, maths rewards, and native iPhone enforcement scaffolding.

The parent interface is a standards-based web dashboard, usable from a Mac or phone. Each child's iPhone runs Family Quests, a SwiftUI companion using FamilyControls, ManagedSettings, and a DeviceActivity monitor extension. A self-hosted Python API owns policy inheritance, pairing, grading, and the reward ledger.

This is a development MVP, not a production child-safety product. The backend and pure Swift quota logic have been exercised here. The iOS app has not been built with an Apple SDK or tested on a physical iPhone. Signing, CI, provisioning, and distribution are deliberately left to the repository owner.

Included

  • One household, multiple child profiles, one active iPhone per child. Shared rules with sparse per-child overrides and revision conflict detection.
  • Daily entertainment allowance, configurable allowed hours, and capped daily bonuses. Example: five correct arithmetic answers earn ten usage minutes.
  • Server-generated addition/subtraction challenges, server-side grading, expiring attempts, and transactional, idempotent reward issuance.
  • Single-use pairing/configuration codes, scoped device tokens, parent cookie sessions, revocation, Keychain storage, and explicit device acknowledgements.
  • Native app selection and shielding, usage-threshold monitoring, custom shield UI, and a Close action. Cached rules and expired-bonus handling do not require the backend to run continuously.
  • Docker/Compose, pinned Python dependencies, XcodeGen specification, tests, and a physical-device acceptance checklist. No build pipeline or signing secrets.

Start the backend and parent dashboard

Python 3.12+ is required for local development (tested with 3.13). Docker uses Python 3.13.

git clone git@github.com:felixfoertsch/ios-advanced-parental-controls.git
cd ios-advanced-parental-controls
cp .env.example .env
python3 -c 'import secrets; print(secrets.token_urlsafe(32))'
# Put the generated value into APC_ADMIN_TOKEN in .env.
# Set APC_ORIGIN to the exact browser origin, e.g. https://family.example.net.
docker compose up --build

The default loopback dashboard is http://localhost:8000. Sign in using APC_ADMIN_TOKEN. Add child profiles; there are no seeded real children, credentials, or family records.

For a non-Docker development process:

make bootstrap
set -a; . ./.env; set +a
make serve

make serve binds only to loopback. For physical phones, put the service behind your HTTPS reverse proxy, use a certificate trusted by the phone, and set APC_ORIGIN to that HTTPS origin. Compose also binds to host loopback; attach your proxy appropriately. There is no automatic TLS/proxy configuration. The native Release app refuses plain HTTP; Debug permits HTTP only on loopback, not arbitrary LAN addresses.

Generate and build the iPhone project

On the Mac build server, install XcodeGen (2.42+) and use an Xcode version suitable for the device OS. The deployment target is iOS 18.0; no unverified iOS 27-specific API is assumed.

cp ios/Config/Local.xcconfig.example ios/Config/Local.xcconfig
# Set your development team, bundle prefix, and App Group in Local.xcconfig.
make ios-project
xcodebuild -project ios/AdvancedParentalControls.xcodeproj \
  -scheme FamilyQuests -configuration Debug \
  -destination 'generic/platform=iOS' build

The generated project contains the app, DeviceActivity monitor, Shield Configuration, and Shield Action targets. It is intentionally not checked into git; ios/project.yml is the source of truth. Configure Family Controls and the same App Group on all four App IDs/profiles. Read Apple setup before attempting an install or archive. Icons, distribution privacy declarations, entitlement approval, and signing are still owner tasks.

In the web dashboard, create a pairing code. On the child's phone, enter the HTTPS server origin and code, obtain guardian approval, and select individual entertainment apps. Leave Family Quests, Phone, messaging needed for safety, and school apps accessible. Whole categories and websites are intentionally rejected in v0. Later selection changes need a new configuration code from the parent dashboard.

Tests

make bootstrap
make test                    # Python API tests + Swift package tests + JS syntax
# Optional real Chromium DOM / real ASGI-backend smoke test, without a network deployment:
.venv/bin/pip install playwright==1.57.0
.venv/bin/playwright install chromium
.venv/bin/python scripts/browser_smoke.py

For an existing Chromium installation, set CHROMIUM_PATH=/path/to/chromium for the smoke script. APC_SCREENSHOT=/path/to/screenshot.png optionally captures its synthetic family dashboard. This script bridges browser fetches to TestClient; it is not a deployed HTTP/TLS or real-device test.

Initial verification: 21 Python tests, 10 Swift tests, browser/ASGI smoke, JavaScript syntax, Swift syntax, and plist/YAML checks passed. The networking Swift source was also type-checked with Linux Foundation. Xcode generation/build, Docker image execution, and physical Screen Time behavior were not validated in this environment. See acceptance checklist.

Important v0 boundaries

Rules sync when the child app opens, returns to the foreground, or the child taps Sync. There is no APNs/background remote sync yet. The parent sees the last reported revision and status, not a promise of immediate enforcement. A stricter native Apple restriction can still block an app after this app grants credit.

Time credits are usage allowance, not a wall-clock unlock period. The native monitor registers a ladder of cumulative thresholds, including the daily cap. Earning a normal reward does not restart monitoring. Exact remaining usage is not exposed as a fake live countdown. DeviceActivity callback reliability and cumulative counting after a policy/selection change require physical testing.

One same-day allowed window applies every day. There are no separate weekend rules, multi-device pooled budgets, manual chores, learning-app integrations, Android agent, cloud accounts, telemetry dashboards, or native Screen Time-settings import. The family timezone becomes immutable after the first reward in v0 to prevent accidental double-day issuance; proper timezone migration is deferred.

Repository map

backend/src/apc/        API, SQLite persistence, validation, parent web dashboard
backend/tests/         API, authorization, concurrency, cap and timezone tests
packages/PolicyCore/   Platform-independent Swift policy/quota logic and tests
ios/App/               SwiftUI companion, API client, Keychain credentials
ios/Shared/            App Group state and Apple enforcement adapter
ios/Monitor/           DeviceActivity callbacks
ios/Shield*/           Shield presentation and Close action
ios/project.yml        Reproducible XcodeGen project specification
docs/                  Architecture, Apple setup, acceptance and security notes

The API schema is served at /openapi.json; its v0 return envelopes are described in architecture. Read security and operations before putting real family data into the service.

S
Description
No description provided
Readme
90 KiB
Languages
Swift 44.7%
Python 43.5%
JavaScript 8.3%
HTML 2.4%
Makefile 0.6%
Other 0.5%