I just spent (far too many) hours debugging why my...
# compose-ios
m
I just spent (far too many) hours debugging why my method, marked as
@Composable
, wasn't compiled to native. I discovered that when I added the
@Composable
annotation to a top-level function, it wasn't generated in the resulting
.h
file. @Dima Avdeev, perhaps it would be beneficial to include this information in the documentation? Thank you!
p
@Composable
functions are slightly modified by compose compiler (additional parameters added), so they are not expected to be called directly from outside world (you have no information about which parameters you need to provide to such function) therefore, they are not exported in native artifacts
2
m
@Pavel Shishkin Thanks for the explanation, however I still stand the point that without this knowledge it is a nightmare to debug and should be specified in the docs 😶
👍 1
p
sure, we will definitely clarify this in the documentation can you tell us a little more about your case: why was it important?
m
thanks! In my case I added a top level function that remembered some state and I tried to use it on the ios side of things. I got confused when I saw that all my methods and classes are visible and the composable one is not. I am using cocapods for integration btw. It was also misleading because i could use the method in Android
o
i could use the method in Android
Could you please explain or show how you use it? Do i understand correctly that you try to call a Composable function from non-composable code/function/etc?
👍 1
i
It was also misleading because i could use the method in Android
Could you clarify this? Because it sounds as incorrect approach in general. You cannot just call composable functions outside of composable context. It sounds similar to question like "why I cannot call composable functions from onClick callback"
m
Composable methods exported from KMM library are visible from the
androidApp
(i.e the
MainView()
method in todoapp example from CMP repo - https://github.com/JetBrains/compose-multiplatform/blob/master/examples/todoapp-li[…]App/src/androidMain/kotlin/example/todoapp/lite/MainActivity.kt) But if you try to call MainView from ios it is just not there. Now I understand why but imo it could not be clear at first glance
I know that calling composables in iOS is not supported/correct approach but I would rather expect a crash when I do call it or some other kind of error than just no method to call at first place
o
MainView()
in the example above is called from another Composable. So if you want to call a Composable on ios from kotlin code (same as an example above - it's called in kotlin code), it's possible.
m
Yes, but it is not exported to native, right? So it is inconsistent. Let's say I built a library that has some methods marked as @Composable and I target Android and iOS. I can call those methods when I import the library on Android but those methods do not exist on native (Swift/ObjC) iOS. Sorry for not making things clear
o
I can call those methods when I import the library on Android
only when using kotlin, not java 🙂
but those methods do not exist on native (Swift/ObjC) iOS
that's true, they're not exposed to ObjC. but can be called in kotlin code. Kotlin is required because Composable calls are expected to be transformed by the Compose compiler plugin for Kotlin. Even if they were exposed to ObjC, it would be quite difficult to properly build a correct composition manually. _ I think, the takeaway from this thread is to explicitly note this behaviour in the documentation.
🙌 1
m
I did not know about the java incompatibility - thanks for pointing that out 🙌
p
also, there you can read about compose integration with UiKit/SwiftUi https://www.jetbrains.com/help/kotlin-multiplatform-dev/compose-ios-ui-integration.html
👀 1