iOS Demo Mode — offline Astra Hospital showcase¶
Built 2026-07-21 for Medicall Chennai (with the web demo at demo.astradial.com). Ships in astradial-astracall from v1.2.0 (build 8, TestFlight). Companion doc: development/demo-portal-plan.md (web).
What it is¶
A fully offline demo inside the REAL AstraCall app: fake org Astra Hospital (ext 1001, "Muthu Manikandan", owner role), no login, no SIP, no Firebase, no network. Every screen shows call-heavy fixture data; calls are simulated in-UI with a bundled audio clip. Demo off = byte-identical behavior — every branch is behind the Demo.isOn flag (UserDefaults astradial_demo).
Entering / exiting¶
| Action | How |
|---|---|
| Enter (primary) | Long-press the app icon on the home screen → "Demo Mode" (static UIApplicationShortcutItems; cold + warm launch handled via AppDelegate/SceneDelegate in AstraCallApp.swift) |
| Enter (fallback) | Long-press the AstraDial logo ~1.5 s on the onboarding welcome screen |
| Exit | Green ● DEMO pill (top-right of main tabs) → "Exit demo" → back to login |
| Reset | Fixtures regenerate at every launch; dates are relative (today/T-1/T-2) so data always reads current |
Architecture (all in astradial-astracall)¶
AstraCall/Demo.swift— the flag, all fixtures (pulse ~700 inbound/day with business-hours curve, 18 tickets with callbacks, 22 recents, 10-user org directory), bundleddemo-audio.mp3player, andDemoCall(simulated outgoing/incoming: TelecomManager flags +onCallerName/onStateTextcallbacks drive the realNativeCallView— no SIP client involved).- Seams (each one
if Demo.isOnearly-return):AstradialAPIConfig.isConfigured(the master gate),fetchPulse,fetchTickets,fetchUsers,orgUsersRaw,HistoryListViewModel.load,AstradialDialer.call,AstraCallManager.endActiveCalls,CoreContext.restore→demoAttach()(fake registered line; stops any real client first),MDSession(owner session), live-calls phonebook (skipped). - Recording/greeting playback in demo points at the bundled clip: "This is a demo audio. To create your account, visit editor dot astradial dot com."
Stall usage¶
- Install from TestFlight (internal group). 2. Airplane mode ON. 3. Home-screen long-press → Demo Mode. 4. Walkthrough: Analytics → Recents (play a recording) → dial any number (connects after ~2 s, audio plays) → DEMO pill → "Simulate incoming call" (Reception Desk rings, connects) → Tickets. Hangup works; everything else shows normal UI but doesn't mutate.
Release notes / gotchas¶
- Version trains: an App-Store-approved marketing version is CLOSED for new builds (1.0/build 7 was rejected with code 90186). Always bump
MARKETING_VERSIONpast the released version — demo shipped as 1.2.0 build 8. Build-number rules + log live inApp Store/A tour to app store.md. - WebRTC dSYM warning on upload is permanent and harmless — stasel/WebRTC is a stripped prebuilt binary with no published dSYMs (UUID verified matching). It never blocks TestFlight/review; only WebRTC-internal crash frames stay unsymbolicated. Do not disable
uploadSymbolsfor it. - CLI export with the ASC key fails (cloud-signing permission) — distribution goes through Xcode Organizer with Hari's Apple ID, same as build 6.
- Demo mode ships in the store binary too. That's intentional: it doubles as a "try before you sign up" path and gives App Review a working demo (helps guideline 2.1 review).