A WWDC-week social map: developers sign in with Apple, set a bio + avatar, and see themselves and every other registered user as live pins on a map so they can find each other.
- iOS app (
WWDCFindMy/) — SwiftUI, iOS 26, Sign in with Apple, always-on background location, MapKit. - Backend (
Server/) — Vapor + Fluent + Postgres, validates Apple identity tokens, issues session JWTs, stores profiles/locations, serves uploaded avatars.
iOS app ──Sign in with Apple──▶ POST /auth/apple (verifies Apple token, issues session JWT)
──Bearer session JWT──▶ GET /me (validate token on launch)
GET /users (everyone with a location → map pins)
POST /location (throttled background updates)
PATCH /profile (bio / name)
POST /avatar (multipart image → saved to disk)
GET /avatars/:file (public, served from disk)
The map refreshes by polling GET /users every ~15s while open; each device posts
its own location on significant movement (> 25 m or > 30 s) via CLLocationUpdate.
Requires Docker (for Postgres) and the Swift 6 toolchain.
cd Server
docker compose up -d # Postgres on :5432
APP_JWT_SECRET=dev-secret swift run App migrate --yes
APP_JWT_SECRET=dev-secret swift run App serve --hostname 0.0.0.0 --port 8080
swift test # route/auth tests (no DB needed)The iOS app's ServerConfig points the simulator at http://localhost:8080.
| Var | Purpose | Local default |
|---|---|---|
DATABASE_URL |
Postgres connection string | (falls back to local DATABASE_*) |
APP_JWT_SECRET |
HMAC secret for session JWTs | insecure dev default |
APPLE_BUNDLE_ID |
Audience for Apple token verification | com.kylebashour.WWDCFindMy |
PUBLIC_BASE_URL |
Base for avatar URLs | http://localhost:8080 |
AVATAR_DIR |
Where avatars are written | Public/avatars |
cd Server
fly launch --no-deploy # creates the app (or reuse fly.toml)
fly postgres create # managed Postgres; attach sets DATABASE_URL
fly postgres attach <pg-app-name>
fly volumes create avatars --size 1 # persistent disk for avatars (mounted at /data)
fly secrets set APP_JWT_SECRET="$(openssl rand -hex 32)"
fly deploy # release_command runs migrationsfly.toml sets AVATAR_DIR=/data/avatars, PUBLIC_BASE_URL, and APPLE_BUNDLE_ID.
After deploy, update ServerConfig.baseURL (device build) to the Fly host.
Open WWDCFindMy.xcodeproj, build for an iOS 26 simulator or device.
- Capabilities: Sign in with Apple (
WWDCFindMy/WWDCFindMy.entitlements), Background Modes → Location updates (Info.plist). - Sign in with Apple requires the simulator/device to be signed into an Apple ID.
- Background location must be verified on a real iOS 26 device — the blue status indicator and true backgrounding don't fully reproduce in the simulator. Use Xcode's Debug → Simulate Location to feed movement.
Out of scope for WWDC week (easy follow-ups): real-time push (APNs/websockets) instead of polling, a precise/approximate location toggle, account deletion, and moving avatars to object storage (S3/R2).