Symptom

Apple rejected the iOS build reporting the app crashed on launch. No crash log was provided and the crash did not reproduce locally (Debug builds in the simulator / on a dev device).

Root cause

Two iOS-only structural hazards in the launch path, either of which crashes the app in ways that are invisible on JVM targets:

  1. initKoin() ran inside the ComposeUIViewController content lambda (MainViewController.kt). Android calls startKoin once in Application.onCreate and desktop in main(), but on iOS any second invocation of MainViewController() — SwiftUI recreating the UIViewControllerRepresentable after a scene reconnect (memory pressure, backgrounding on the review device farm) — called startKoin again, which throws KoinApplicationAlreadyStartedException and kills the app immediately. To a reviewer that is “crashed on launch.”

  2. The unqualified single<CoroutineScope> in sharedModule (the scope ClientNodeManager.init launches startup work into) had no CoroutineExceptionHandler. On Kotlin/Native an unhandled coroutine exception terminates the whole process; on JVM targets it only logs. Any exception in the startup coroutine (serialization, storage, node-bookkeeping) was therefore a silent log line locally and a hard crash on iOS.

Additionally, no setUnhandledExceptionHook was installed, so a fatal Kotlin exception left nothing diagnosable — Apple crash reports cannot symbolicate Kotlin/Native frames, which is why the rejection came with no usable log.

Fix

Prevention