Rafael Costa
10/23/2025, 5:05 PMComposeUIViewController -> stack trace in the 🧵, as far as I can see, it happens on kfun:androidx.compose.ui.util#trace call.
Is there any known issue on testflight builds? or anything special that it does that could hint at why this happens?Rafael Costa
10/23/2025, 5:11 PM6 libc++abi.dylib 0x000000019aa92314 __cxxabiv1::failed_throw(__cxxabiv1::__cxa_exception*) + 88 (cxa_exception.cpp:152)
7 libc++abi.dylib 0x000000019aa922bc __cxa_throw + 92 (cxa_exception.cpp:299)
8 TerminalSharedKMP 0x0000000105468a2c ExceptionObjHolder::Throw(ObjHeader*) + 52
9 TerminalSharedKMP 0x00000001054689f8 ThrowException + 12
10 TerminalSharedKMP 0x000000010430d98c kfun:androidx.compose.ui.util#trace(kotlin.String;kotlin.Function0<0:0>){0§<kotlin.Any?>}0:0 + 1084 (Trace.uikit.kt:44)
11 TerminalSharedKMP 0x000000010430d98c <inlined-out:postponeInvalidation> + 1084 (BaseComposeScene.skiko.kt:87)
12 TerminalSharedKMP 0x000000010430d98c kfun:androidx.compose.ui.scene.BaseComposeScene#setContent(kotlin.Function2<androidx.compose.runtime.Composer,kotlin.Int,kotlin.Unit>){} + 3000 (BaseComposeScene.skiko.kt:138)
13 TerminalSharedKMP 0x00000001043dbcc4 kfun:androidx.compose.ui.scene.ComposeScene#setContent(kotlin.Function2<androidx.compose.runtime.Composer,kotlin.Int,kotlin.Unit>){}-trampoline + 156 (ComposeScene.skiko.kt:176)
14 TerminalSharedKMP 0x00000001043dbcc4 kfun:androidx.compose.ui.scene.ComposeSceneMediator.ComposeSceneMediator$setContent$1.invoke#internal + 540 (ComposeSceneMediator.uikit.kt:526)
15 TerminalSharedKMP 0x00000001043dbcc4 kfun:androidx.compose.ui.scene.ComposeSceneMediator.ComposeSceneMediator$setContent$1.$<bridge-DN>invoke(){}#internal + 604 (ComposeSceneMediator.uikit.kt:523)
16 TerminalSharedKMP 0x00000001043ec754 kfun:kotlin.Function0#invoke(){}1:0-trampoline + 156 ([K][Suspend]Functions:1)
17 TerminalSharedKMP 0x00000001043ec754 kfun:androidx.compose.ui.scene.UIKitTransparentContainerView.UIKitTransparentContainerView$runOnceOnAppeared$1.invoke#internal + 208 (UIKitTransparentContainerView.kt:42)
18 TerminalSharedKMP 0x00000001043ec754 kfun:androidx.compose.ui.scene.UIKitTransparentContainerView.UIKitTransparentContainerView$runOnceOnAppeared$1.$<bridge-DN>invoke(){}#internal + 256 (UIKitTransparentContainerView.kt:41)
19 TerminalSharedKMP 0x00000001043eb8d4 kfun:kotlin.Function0#invoke(){}1:0-trampoline + 156 ([K][Suspend]Functions:1)
20 TerminalSharedKMP 0x00000001043eb8d4 kfun:androidx.compose.ui.scene.UIKitTransparentContainerView.runOnAppearedIfEligible#internal + 1144 (UIKitTransparentContainerView.kt:56)
21 TerminalSharedKMP 0x00000001043ebe0c kfun:androidx.compose.ui.scene.UIKitTransparentContainerView#objc:layoutSubviews + 500 (UIKitTransparentContainerView.kt:64)
22 TerminalSharedKMP 0x0000000105437f00Andrei Salavei
10/24/2025, 10:42 AM1.9.1 or 1.10.0-alpha03.Rafael Costa
10/24/2025, 10:42 AMRafael Costa
10/24/2025, 10:43 AMRafael Costa
10/24/2025, 10:43 AMRafael Costa
10/24/2025, 10:45 AMRafael Costa
10/24/2025, 11:12 AMpublic class EposBridge(
private val provider: FlutterKmpProvider, // ℹ️ YES THE APPLICATION IS FLUTTER AND HAS FLUTTER NATIVE PLUGIN HERE - NOT SURE IF IT IS RELEVANT INFO
) {
private val scope: CoroutineScope by lazy { MainScope() }
private var eposController: EposSdkController? = null
public fun startEpos() {
scope.launch {
val storeId = provider.getCurrentStoreId() // ℹ️ SUSPEND FUNCTION CALL
if (storeId.isEmpty()) {
return@launch
}
if (storeId != CurrentStoreHolder.get()) { // ℹ️ SUSPEND FUNCTION CALL
eposController = null
CurrentStoreHolder.set(storeId) // ℹ️ SUSPEND FUNCTION CALL
}
val controller = getOrCreateEposController()
controller.startEpos( // ℹ️ SHOWS MAIN COMPOSABLE - see below
storeId = storeId,
currency = provider.getCurrentCurrency().defaultCurrency
)
}
}
private suspend fun getOrCreateEposController(): EposSdkController {
if (eposController == null) {
eposController = getEposSdkController(
isProdEnvironment = provider.isProdEnvironment(), // ℹ️ SUSPEND FUNCTION CALL
// ... other parameters
)
}
return eposController!!
}
}
ℹ️ The above startEpos call will do something like this:
internal actual fun platformStartEposSdk() {
val controller = UIApplication.sharedApplication.keyWindow?.rootViewController
val mainController = ComposeUIViewController {
Column(modifier = Modifier.systemBarsPadding()) {
EposMainComposable()
}
}
mainController.modalPresentationStyle = UIModalPresentationFullScreen
controller?.presentViewController(mainController, true, null)
}Andrei Salavei
10/24/2025, 11:59 AMEposMainComposable() with some dummy, or just remove this line it completely. If the app still crashes, it most likely the case described above.Rafael Costa
10/24/2025, 12:07 PMRafael Costa
10/24/2025, 12:08 PMRafael Costa
10/24/2025, 12:09 PMRafael Costa
10/24/2025, 12:23 PMAndrei Salavei
10/24/2025, 1:09 PMEposMainComposable()
• Try to open View Controller with EposMainComposable() , but without running Flutter
• You can also assemble started project with both, Compose and Flutter and try to present one from another.
• Try using new version of Compose
Notice also that we’re able to have working test flight build with a simpler “initialising” / main composable codeOk, acknowledged - we're keeping attention on every release
But if this is the case, would it work on non test flight builds?That's unknown area - if it is the case, it's hard to predict how it can or cannot work.
Rafael Costa
10/24/2025, 1:40 PMLaunchedEffect(Unit) {
logger.i("MainViewController composed first time")
}
Column(modifier = Modifier.systemBarsPadding()) {
Text("Hello from iOS!")
}Rafael Costa
10/24/2025, 2:50 PMEposMainComposable, worked.Rafael Costa
10/24/2025, 2:51 PMRafael Costa
10/24/2025, 2:52 PMEposMainComposableRafael Costa
10/24/2025, 3:17 PMRafael Costa
10/24/2025, 3:17 PMRafael Costa
10/24/2025, 3:18 PMAndrei Salavei
10/24/2025, 4:46 PMEposMainComposable ?Andrei Salavei
10/24/2025, 4:47 PMRafael Costa
10/24/2025, 4:51 PMHm... do you have code that parses HTML or something connected with web/urls in theI don't think so 🤔?EposMainComposable
Rafael Costa
10/24/2025, 4:52 PMOr something that force runs tasks in iOS run loop - that might be the issue.Hmm, I'm not sure.. Do you have an example of what could do that?
Rafael Costa
10/24/2025, 4:52 PMRafael Costa
10/24/2025, 4:53 PMRafael Costa
10/24/2025, 4:55 PMRafael Costa
10/24/2025, 5:03 PMLaunchedEffect(Unit) {
logger.i("MainViewController composed first time")
}
Column(modifier = Modifier.systemBarsPadding()) {
Text("Hello from iOS!")
}
We did:
@Composable
internal fun EposMainComposable(
) {
var counter by remember { mutableIntStateOf(0) }
TeyaTheme {
Scaffold(modifier = Modifier.statusBarsPadding()) { paddingValues ->
Box(Modifier.padding(paddingValues).fillMaxSize()) {
Column {
Text("Hi, this is EposMainComposable!")
Text("Counter $counter")
Row {
Button(
onClick = { counter++ }
) {
Text("+1")
}
Button(
onClick = { counter-- }
) {
Text("-1")
}
}
}
}
}
}
}
So now we are suspecting the TeyaTheme. It's in an old module that was used by native android app and was changed to KMP module. It still uses both material 2 and material 3 (probably not very common thing).Andrei Salavei
10/27/2025, 8:31 AMHmm, I'm not sure.. Do you have an example of what could do that?Usually it's something ios-specific, like usage if the
RunLoop / NSRunLoop class, or access to other native API connected with dispatch quqe. They usually break the order of tasks execution and may ruin the app.
Apparently our local builds are all working, but not TestFlight onesSorry if the question is not correct,, however - did you try running
release build locally on device?
So now we are suspecting theCurious whats inside... you can send me full implementation in DM for the investigation if you want..TeyaTheme
Rafael Costa
10/27/2025, 11:20 AMSorry if the question is not correct,, however - did you try runningYes we are trying to reproduce locally by making our local builds as close to test flight ones as possible, but so far with no luck. All we have tried was not able to reproduce this crash, only test flight builds are crashing 🤷build locally on device?release
Rafael Costa
10/27/2025, 11:20 AMRafael Costa
10/27/2025, 3:29 PMRafael Costa
10/27/2025, 10:10 PMRafael Costa
10/27/2025, 10:11 PMAndrei Salavei
10/28/2025, 9:56 AMsetUnhandledExceptionHook() or https://github.com/touchlab/CrashKiOS (or other 3rd party tool). In this case the cause of the crash will be much more discoverable.