Hi there - I have a question about how to force a ...
# compose-ios
d
Hi there - I have a question about how to force a recompose, or redraw of the main
ComposeUiViewController
from iOS. I would like to trigger a redraw/recompose when the iOS app is opened by another app with a deeplink. Is there a way to do that? I have tried to use an
EnvironmentObject
to trigger a redraw but I’m a little lost.
c
I don’t believe recomposition can be “forced” without a change to State. The idea of Compose is a “pure transformation” from State to UI, so if there are no changes to state, then the UI should be the exact same. If you’re reading values that are not backed by
State<T>
objects, you no longer have a “pure” UI and unexpected issues can arise. Forcing a recomposition without any change to state variables won’t have any effect on the UI. So if you want the UI to react to or display differently when opened via deepLinks, you should update a state variable with data from the deepLink. The UI then reads that state variable and responds appropriately when it changes as a result of the deepLink
d
Thanks for the insight. So I need to find a way to pass a
State<T>
from the SwiftUI code into the
MainViewController
and then have the composable react accordingly
Unless I can capture iOS deeplinks directly in kotlin
c
I’m not too familiar with Kotlin/Swift interop, or what the deepLink handling of iOS looks like, but I’d imagine you could just keep a top-level state property and directly update it from Swift code. Then the Compose UI reads from that state variable.
Copy code
//deepLinkHander.kt
val deepLinkUri = mutableStateOf<String?>(null)

@Composable
fun Application() { 
 	Text(deepLinkUri.value)   
}

//deepLinkHanderiOS.swift
onDeepLinkHandled { (uri) -> void in
   DeepLinkHander.deepLinkUri.setValue(uri)
}
d
Looks promising - I’ll give it a go. Thanks again for your help
a
> I don’t believe recomposition can be “forced” without a change to State. There is a way actually. You can get the recompose scope by calling
currentRecomposeScope
in a composable function, and call
scope.invalidate()
elsewhere to force a recomposition.
d
@Albert Chang thanks for the input. In the end I was able to pass state directly using a similar method outlined above by @Casey Brooks:
Copy code
// in Kotlin: DeepLinkHandler.kt
val deepLinkUri = MutableStateFlow<String?>(null)

// in Swift
func handleDeepLink(_ url: URL) {
    DeepLinkHandlerKt.deepLinkUri.tryEmit(value: url)
}
The interop works seamlessly 👍