Moving a fully functional browser-native clinical simulator to the iOS App Store sounds straightforward. Spoiler: it is not. Guideline rejections, reviewer confusion, database bugs that only surface under review conditions, and structural requirements you didn't know existed — this is what the process actually looks like from the inside.

We built the ACLSMED Clinical Suite as a browser-native platform first. The decision was deliberate: zero friction distribution, no installation, runs anywhere. A clinician with a hospital laptop, a tablet, or a personal MacBook can launch the full simulator in a browser tab.

The iOS native build is a different product with different constraints. And the App Store review process, while ultimately navigable, will teach you things about your architecture that you didn't know you needed to learn.

Why native at all?

If the web version works, why build native iOS? The answer isn't prestige — it's capability. Specific iOS features that don't exist in a browser context: Apple MultipeerConnectivity for peer-to-peer device pairing over local network without internet, background audio for scenario narration, deeper haptic feedback during defibrillation events, and native performance for waveform rendering on older iPad hardware.

More practically: the App Store is where clinicians look for clinical tools. "It's available on the web" and "it's on the App Store" are not equivalent trust signals to a hospital education coordinator evaluating simulation platforms.

The Guideline 2.1(a) rejection

App Store Guideline 2.1(a) is the catch-all: the app must function correctly for reviewers. Our build came back with a 2.1(a) rejection. The message was sparse, as they always are.

Guideline 2.1(a) — Performance

We were unable to sign in and test the app's features. Please provide a working demo account or test credentials in the App Review Notes that allow us to fully access the features of the app.

The immediate assumption: credentials were wrong. We checked. Credentials were correct. The demo account existed. Login worked on every device we owned. The actual root cause took an hour of debugging to find: device role slots.

The seat exhaustion bug

The ACLSMED iOS app is a multi-device simulator. One device becomes the Monitor/Defibrillator. Another becomes the IV pump. A third becomes the Ventilator. Each device "claims" a role slot in the user's profile in Supabase — stored as a JSONB column called role_slots in the profiles table.

During development, we'd tested on every physical device in the studio: an iPad Pro, two iPad Airs, and a personal iPhone. All four device slots in the demo account were filled by debug devices — devices that no longer existed in the test environment but whose slot claims were never cleaned up.

When the Apple reviewer downloaded the app on their review device and attempted to sign in, every role slot in the demo account was already occupied. The app correctly refused to assign a new role. From the reviewer's perspective, the app didn't work.

Root cause

All 4 role slots in the reviewer demo account were claimed by stale debug devices. The app functioned correctly — the test account state was wrong. Nearly impossible to catch in a dev environment where you control the test devices.

The fix — two layers

Database cleanup: Clear the role_slots JSONB on the demo account in Supabase before resubmission. Verify that the account presents as a fresh, zero-slot state to any new device attempting to claim a role.

In-app seat recovery: The database fix alone isn't enough for production. Users will inevitably exhaust their device slots through normal behavior — device resets, app reinstalls, lost tablets. An in-app seat management panel in the role picker lets users view occupied slots and reclaim them without requiring a database intervention.

"The App Store reviewer is the most honest user test you'll ever get. They have no goodwill, no context, and no patience for flows that require workarounds."

Lessons for other developer-clinicians

01

Test on a completely clean account

The demo account you provide to App Review must be in a genuinely fresh state. Not "probably fresh" — verifiably zero. Check the database directly.

02

Seat logic needs in-app recovery

Any resource-claiming system needs a self-service recovery path. Users will exhaust slots through normal behavior. Don't require support intervention.

03

Review notes are your only channel

Write them clearly, step-by-step. "Sign in with X, select Y role, you should see Z" — not paragraphs of context.

04

2.1(a) means "we couldn't test it"

When a reviewer can't complete a flow, they file 2.1(a). Debug the reviewer experience, not the codebase.

The rewarding part

Worth it anyway.

  • The App Store reaches clinicians where they already look for tools
  • MultipeerConnectivity unlocks local pairing without internet dependency
  • Native waveform rendering is a step-change over Canvas + requestAnimationFrame
  • Background audio that survives a screen lock — not possible in a browser
  • Review rejections surface real production bugs before users hit them

The web version is live now

While the iOS build completes review, the full ACLSMED Clinical Suite runs in any browser — no installation, full 34-scenario library, synchronized multi-device support.

Launch the Simulator