My shared module contains Repository class which has two functions that return a list of items wrapped in a custom class extending Flow
called CFlow.
I took the code for CFlow
from kotlinconf-app and here:
fun <T> Flow<T>.asCFlow(): CFlow<T> = CFlow(this)
class CFlow<T>(private val origin: Flow<T>) : Flow<T> by origin {
fun watch(block: (T) -> Unit): Closeable {
val job = Job()
onEach {
block(it)
}.launchIn(CoroutineScope(Dispatchers.Main + job))
return object : Closeable {
override fun close() {
job.cancel()
}
}
}
}
Repository example functions:
fun getData1(): CFlow<List<Profile>>
fun getData2(): CFlow<List<String>>
When I try to call this functions in iOS swift code the return type of the functions get converted to CFlow<NSArray>
and inside of watch function the type of array is Any.
This is weird because in both kotlinconf-app and here the return types of functions are preserved and there is no casting involved in their codebase.
Question: How can I make the type of CFlow to be known in Xcode iOS project?
Android Studio version: 4.1.1
Kotlin lang and plugin version: 1.4.21
Kotlin Multiplatform Mobile plugin version: 0.2.0
Xcode version: 12.2
This is because there are no generics in Objective-C. Arrays are ordered collections of objects.
So using any generic collection type in Kotlin, will lose it's type when translated to NSArray
I believe you have three options here:
fun observeItems(onChange: (List<Item>) -> Unit) {
items.onEach {
onChange(it)
}.launchIn(coroutineScope)
}
Exposing a dispose function to iOS
fun dispose() {
coroutineScope.cancel()
}
And consuming like this:
repo.observeItems { items in
...
}
But definitely this is more work and hopefully these interop issues will be solved along the way