Skip to content

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), bundled demo-audio.mp3 player, and DemoCall (simulated outgoing/incoming: TelecomManager flags + onCallerName/onStateText callbacks drive the real NativeCallView — no SIP client involved).
  • Seams (each one if Demo.isOn early-return): AstradialAPIConfig.isConfigured (the master gate), fetchPulse, fetchTickets, fetchUsers, orgUsersRaw, HistoryListViewModel.load, AstradialDialer.call, AstraCallManager.endActiveCalls, CoreContext.restoredemoAttach() (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

  1. 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_VERSION past the released version — demo shipped as 1.2.0 build 8. Build-number rules + log live in App 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 uploadSymbols for 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).