A native iOS instant/disposable-camera app. Shoot now, see it later; photos hide and "develop" over time, then reveal with an instant-film look baked in at capture. Invite-only.
- SwiftUI (iOS 26 target),
@Observablethroughout, noObservableObject - AVFoundation for capture, Core Image for the instant-film processing
- Supabase: Postgres + Row Level Security, email OTP auth, private Storage bucket
- iOS 26 Liquid Glass styling app-wide
- xcodegen-managed project (
project.ymlis the source of truth)
- Email OTP sign-in, gated by an invite allowlist; users can self-invite with a friend's code
- Full-screen camera with a film-strip picker and instant-film look baked in at capture
- Darkroom: developing placeholders, countdown, and reveal moment
- Rolls: shared friend groups via 6-char invite codes (max 50 members)
- Signature FLIM Original look: fitted 3D LUT + scene-adaptive exposure, shipped as flim.cube
- Social layer: photo feed with posts/captions, follows, reactions/comments, user pages, activity view, discovery/search, reporting + blocking (RLS-enforced, bidirectional)
- Remote push notifications (APNs via Edge Functions; local fallback on-device)
- Daily digest summarizing friends' posts instead of individual notifications
Flim/
Config/ Supabase client
Models/ AppUser, Roll, Photo, FilmStock, Social
Services/ Auth, Photo, Roll, Feed, Notification, RemotePush, InstantFilmProcessor
Views/ Auth, Camera, Darkroom, Rolls, Profile, Feed, Main, Components
supabase/
schema.sql Tables, RLS policies, and RPCs
migrations/ Idempotent SQL migrations (applied to production, mirrored in schema.sql)
functions/ Edge Functions (send-develop-push, send-social-push, send-daily-digest)
push/ device_tokens migration + APNs setup docs (function code lives in functions/)
web/ Invite landing page + legal site (Vercel)
scripts/ LUT fitting (fit_lut.py)
project.yml xcodegen project definition
docs/ Release, setup and operations guides (see below)
| File | What it covers |
|---|---|
docs/APP_STORE.md |
Store listing copy, release notes per version, App Privacy worksheet, App Review sign-in |
docs/CRASH_TRIAGE.md |
Turning a crash_diagnostics row into a file and line number, with no Apple Developer account |
docs/LAUNCH_RUNBOOK.md |
Launch checklist and backlog |
docs/TESTFLIGHT_SETUP.md |
CI, signing and TestFlight distribution |
docs/UNIVERSAL_LINKS.md |
Associated domains, roll invites (/join/CODE) and personal invites (/i/CODE) |
docs/LUTS.md |
Fitting the film look from calibration pairs |
docs/PRIVACY.md |
Privacy policy source |
- macOS with full Xcode 26.x (Command Line Tools alone is not enough)
xcodegen:brew install xcodegen
# Generate the Xcode project from project.yml
xcodegen generate
# Build for the simulator
DEVELOPER_DIR=/Applications/Xcode.app/Contents/Developer \
xcodebuild -project Flim.xcodeproj -scheme Flim \
-destination 'generic/platform=iOS Simulator' buildThen open Flim.xcodeproj in Xcode and run on an iOS 26 simulator or device.
- Paste migrations, then run
supabase/schema.sqlin the SQL editor:supabase/migrations/holds paste-ready, idempotent migrations (already applied to production). Paste each into the editor and run once; they are then mirrored inschema.sqlfor historical reference. (New migrations get their own dated file.)schema.sqlis the source of truth for the full schema state (idempotent, safe to re-run). It creates the tables, RLS policies, and RPCs.
- Create a private Storage bucket named
photosand add the per-user policies documented inschema.sql. - Add the project URL and publishable key to
Flim/Config/SupabaseClient.swift.
Each capture uploads three renditions to private Storage:
- full: original processed image (sRGB-tagged JPEG with ICC profile)
- thumb: small grid thumbnail
- feed: ~1400px rendition for feed cards (pixel-identical at display width, ~1/3 the egress)
All files are sRGB-tagged ICC JPEGs; access is via signed URLs (RLS-enforced per user).
FLIM is invite-only. Only allow-listed emails can request a sign-in code:
INSERT INTO public.allowed_emails (email, note) VALUES ('them@example.com', 'Name');Local develop notifications work with no backend. To enable APNs push when roll-mates' photos
develop, deploy the auth key; see supabase/functions/send-develop-push/ and
send-social-push/ for the Edge Function code.