From 0c347d378363ca23692c1d8668c4db8fbf2588dd Mon Sep 17 00:00:00 2001 From: PJ Date: Thu, 23 Apr 2026 17:33:56 +0700 Subject: [PATCH] fix(sdk-ios): check semaphore wait result; resolve port from args and env; register extractors before start --- .../kotlin/app/folio/MainViewController.kt | 2 +- .../kotlin/app/folio/sanderling/IosPauser.kt | 3 ++- .../app/folio/sanderling/SanderlingIos.kt | 18 +++++++++++++++--- 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/examples/folio/composeApp/src/iosMain/kotlin/app/folio/MainViewController.kt b/examples/folio/composeApp/src/iosMain/kotlin/app/folio/MainViewController.kt index 1152cea..04a86e2 100644 --- a/examples/folio/composeApp/src/iosMain/kotlin/app/folio/MainViewController.kt +++ b/examples/folio/composeApp/src/iosMain/kotlin/app/folio/MainViewController.kt @@ -29,11 +29,11 @@ private val backGestureTarget = BackGestureTarget() @OptIn(ExperimentalForeignApi::class) fun MainViewController(): UIViewController { Repository.init() - app.folio.sanderling.SanderlingIos.start() app.folio.sanderling.AuthSnapshots app.folio.sanderling.AccountSnapshots app.folio.sanderling.LedgerSnapshots app.folio.sanderling.NavigationSnapshots + app.folio.sanderling.SanderlingIos.start() val vc = ComposeUIViewController { App() } val gesture = UIScreenEdgePanGestureRecognizer( target = backGestureTarget, diff --git a/examples/folio/composeApp/src/iosMain/kotlin/app/folio/sanderling/IosPauser.kt b/examples/folio/composeApp/src/iosMain/kotlin/app/folio/sanderling/IosPauser.kt index e680427..e9220cd 100644 --- a/examples/folio/composeApp/src/iosMain/kotlin/app/folio/sanderling/IosPauser.kt +++ b/examples/folio/composeApp/src/iosMain/kotlin/app/folio/sanderling/IosPauser.kt @@ -15,7 +15,8 @@ internal object IosPauser { dispatch_semaphore_signal(snapshotReady) dispatch_semaphore_wait(resumeGate, dispatch_time(DISPATCH_TIME_NOW, 5_000_000_000L)) } - dispatch_semaphore_wait(snapshotReady, dispatch_time(DISPATCH_TIME_NOW, 5_000_000_000L)) + val waited = dispatch_semaphore_wait(snapshotReady, dispatch_time(DISPATCH_TIME_NOW, 5_000_000_000L)) + check(waited == 0L) { "snapshot timed out: main thread did not signal within 5s" } return capturedSnapshot } diff --git a/examples/folio/composeApp/src/iosMain/kotlin/app/folio/sanderling/SanderlingIos.kt b/examples/folio/composeApp/src/iosMain/kotlin/app/folio/sanderling/SanderlingIos.kt index c17fe57..f14dd0f 100644 --- a/examples/folio/composeApp/src/iosMain/kotlin/app/folio/sanderling/SanderlingIos.kt +++ b/examples/folio/composeApp/src/iosMain/kotlin/app/folio/sanderling/SanderlingIos.kt @@ -15,12 +15,24 @@ object SanderlingIos { internal val extractors = mutableMapOf Any?>() fun start() { - val env = NSProcessInfo.processInfo.environment - val portStr = env["SANDERLING_PORT"] as? String ?: return - val port = portStr.toIntOrNull() ?: return + val port = resolvePort() ?: return IosAgent.start("127.0.0.1", port) } + private fun resolvePort(): Int? { + // Env var set via SIMCTL_CHILD_SANDERLING_PORT (simctl direct launch). + (NSProcessInfo.processInfo.environment["SANDERLING_PORT"] as? String) + ?.toIntOrNull()?.let { return it } + // Launch argument -SANDERLING_PORT (Maestro simctl launch). + @Suppress("UNCHECKED_CAST") + val args = NSProcessInfo.processInfo.arguments as? List ?: return null + val idx = args.indexOfFirst { it == "-SANDERLING_PORT" } + if (idx >= 0 && idx + 1 < args.size) { + return args[idx + 1].toIntOrNull() + } + return null + } + fun extract(name: String, block: () -> Any?) { extractors[name] = block }