Hi, I am trying to write a composable function whe...
# compose-ios
a
Hi, I am trying to write a composable function where I need to perform few suspend action based on lifecycle of composable. In android world, I was able to achieve this with help of LocalLifecycleOwner as follow. Any suggestion how I can write same code for Kmm-compose since LocalLifecycleOwner is not available.
Copy code
@Composable
fun MyLifecycleComposable() {
    val lifecycleOwner = rememberUpdatedState(LocalLifecycleOwner.current)
    val coroutineScope = rememberCoroutineScope()
    DisposableEffect(key1 = true) {
        val observer = LifecycleEventObserver { _, event ->
            when (event) {
                Lifecycle.Event.ON_STOP -> {
                    coroutineScope.launch {
                        // perform some action
                    }
                }
                Lifecycle.Event.ON_START -> {
                    coroutineScope.launch {
                        // perform some action
                    }
                }
                else -> Unit
            }
        }
        val lifecycle = lifecycleOwner.value.lifecycle
        lifecycle.addObserver(observer)
        onDispose {
            coroutineScope.cancel()
            lifecycle.removeObserver(observer)
        }
    }
}
๐Ÿ‘ 2
d
Hi, You can use LaunchedEffect:
Copy code
LaunchedEffect(Unit) {
    // Here are passed a CoroutineScope as this context
    launch {
        // Here you can call suspend functions
        delay(100)
    }
}
Also, you can extract logic outside of Composable functions and pass external state to it as an argument, And manage CoroutineScope outside of Compose view hierarchy:
Copy code
@Composable
fun MyView(externalStateFlow: StateFlow<String>) {
    val state = externalStateFlow.collectAsState()
    Text(state.value)
}
a
Thanks. Let me try first suggestion as second might not be useful. To give more context, I am trying to open & close my DataSource from start and stop which looks like follow.
Copy code
interface DataSource {
    suspend fun open(): Boolean
    suspend fun close(): Boolean
}
v
Or, for example, how do we pause a video/audio/camera playback when the app minimized (ON_STOP from android)?
d
Copy code
val dataSource: DataSource // get somewhere or put as an argument
    val coroutineScope: CoroutineScope = rememberCoroutineScope()
    DisposableEffect(dataSource) {
        coroutineScope.launch {
            dataSource.open()
        }
        onDispose {
            dataSource.close()
        }
    }
v
But if we minimize the app onDispose will not be called? Will it?
d
Interesting, need to check it
v
Nope, it will not. That is the whole point of the question
d
Ok, I understand
v
Seems like there is no way to pause playbacks in compose mp when we minimize apps
d
No properly handle app stopping (app on background), I think - we need to lift this logic outside of Compose
โž• 1
a
I think you will need a navigation library for this case. So that you could handle minimized app case, or when the screen is closed, etc.
โž• 1
thank you color 1
d
And make it platform dependent
v
I mean, and how a navigation library gonna implement that to provide for us?:)
Maybe we are currently trying to implement PR for a navigation library to support the case
๐Ÿ†’ 1
a
E.g. Decompose provides lifecycle awareness. Other libraries might too.
v
I saw this talk at the compose mp github, but no progress: https://github.com/JetBrains/compose-multiplatform/issues/2915
a
From my point of view, adding lifecycle awareness is a pretty complex task. It's not enough to just add Lifecycle and bind it to Activity/Window/etc. I think this leads to creating a full-featured navigation solution.
โž• 2
That's why it may take a while to design and implement
l
I would argue that lifecycle management is out of scope for a UI library like Compose. I'd rather the Compose API were kept leaner and lifecycle/navigation be handled by another library, be that something like decompose or even Compose navigation (which shares a name with Compose UI, but is and should be a different artifact).
โž• 1
p
๐Ÿ’ฏ agree it shouldn't be part of the compose API but a separate utility.
a
I too feel launch effect along with decompose should be good enough for most of the cases (including my use-case mentioned in the question) and Fragments/Navigation lifecycle level support can be kept out. But it might be opposite to the thinking behind LocalLifecycleOwner support for Android-compose.
a
If Decompose feels cumbersome, one could use Decompose-Router. This library provides Compose-based API and has LocalComponentContext, which implements LifecycleOwner, BackHandlerOwner, etc.
๐Ÿ‘€ 1
v
I mean, they announced that they literally added the whole topic yesterday. https://developer.android.com/jetpack/androidx/releases/lifecycle#2.7.0-alpha01 I am not sure how do we know if that announce only for Jetpack compose or MP compose?
a
I believe that's only for Android
v
Me too, but is kinda weird so you can't tell without digging into sources right?
a
I think everything in Jetpack is either JVM or Android. Unless explicitly announced, like with DataStore, Collections, etc.
v
I heard on the compose IOS-alpha presentation talk from JB that jetpack compose team will be adding new stuff into common if they can
K 1
p
Yeah the lifecycle stuff is a separate package. It would be nice if they make it multiplatform but so far it is Android only. The problem I see, conceptually is that a component lifecycle isn't necessarily the Activity lifecycle. The component lifecycle is more related to its state in its parent component. Eg, shown, hidden, partially shown etc. Googles lifecycle library refers to the plain Activity lifecycle and in most cases we need that but also the component lifecycle relative to its parent too. Googles lifecycle package can't do anything here because this is more of a navigation library problem.
For that they would have to make jetpack navigation multiplatform too. Might be in their schedule already
a
Hi, has anyone figured out any straight forward approch to achieve this ?
v
Not yet. I still have the task for that in my backlog, but I am delaying and doing other stuff
๐Ÿ‘ 1
In blind hope that blessed community resolved everything for me ๐Ÿ˜„
๐Ÿซก 1
p
As indicated above, you have to use one of existing navigation libraries that handles platform lifecycle. The other alternative is handling it yourself. But it would depend on your architecture. I have done similar stuff but the work is really tied to my project architecture, which most likely is a bit different from yours.
โœ… 1