TLDR: If you're demoing a Supabase-backed iOS app live, add a guest mode with hardcoded data. Eighty lines of Swift buys you a demo that runs in airplane mode and never breaks in front of an audience.
the setup
We'd been building a native iOS CRM for tracking KOL (Key Opinion Leader) relationships at an ecommerce business.
Think doctors, researchers, and influencers we partner with — contact records, activity logs, relationship owners. The whole thing backed by Supabase, built in SwiftUI.
It was coming together really well.
Then someone said, "can we show it in a presentation?"
the wall I kept running into
Right around this same stretch I was deep in Supabase auth issues.
The publishable key was the wrong format. DB-nullable fields were silently failing. The Codable decoder config was conflicting with CodingKeys. Relationship owners weren't populating from app_users.
None of these are problems when you're a logged-in developer with a seeded database.
They are ALL problems when you hand someone your phone during a demo.
So what's the actual failure mode? Great question.
You tap "Sign In." The Supabase auth call hangs. Or the key is stale. Or the staging DB has no data. Or it has real data — and now you're scrolling past actual contact names in front of people who shouldn't see them.
I've been in that room. It's not a good time.
what I tried first
My first instinct: just make the real app work perfectly.
(Which — yes. You should do that anyway. But that's a different goal.)
"Make the live backend reliable for demos" is a moving target. Network blips, token expiry, seed data drift — you're managing a whole second layer of risk that has nothing to do with whether your product is actually good.
I kept coming back to the same question: why am I betting the demo on infrastructure I can't control?
the fix that worked
I added a guest/demo mode — a single file, DemoData.swift, with hardcoded sample contacts, relationship records, and activity logs.
Zero Supabase contact. No auth. No network calls.
Tap "Continue as Guest" and the whole app loads instantly with clean, presentable, story-ready data.
One thing I didn't expect: the Xcode project had to be regenerated to pick up the new Swift file. Xcode doesn't auto-discover files added outside the IDE — the xcodeproj just silently ignores them until you regenerate. (Classic Xcode.) That was its own little adventure.
But the actual guest mode logic? Maybe 80 lines of hardcoded structs.
Eighty lines bought me a demo I could run in airplane mode with a dead hotspot and still look completely polished.
why this matters to me
There's a note I keep coming back to from a presentation prep call we did for a marketing client — "live-demo risk wasn't named." We talked about doing AI demos live on a speakerphone, building things in real time, the full theatrical vision. And we almost walked into that room without a safety net.
That stuck with me.
Demo mode is a first-class feature. Not a hack. Not a shortcut. Not something you bolt on after the demo breaks.
The best demos feel effortless because they are effortless — because someone built a path where nothing can go wrong.
Build your demo path separately from your production path. Hardcode the data. Remove every dependency you don't control. Your future self, sweating through a boardroom or a VC call, will absolutely thank you.
P.S. The guest mode stayed in the app long after the demo. Turns out "try it without signing up" is a pretty solid onboarding pattern too.