https://kotlinlang.org logo
a

Alberto

07/24/2020, 5:14 PM
Is reflection handled differently between Android and iOS with Kotlin Multiplatform? Accessing the any member val from KClass returns "Unresolved reference: <name>" when building the iOS variant, but doesn't complain for the Android variant. I've tried also adding the reflect dependency in case.
a

Arkadii Ivanov

07/24/2020, 5:26 PM
a

Alberto

07/24/2020, 5:35 PM
interesting. Is there any example on how to achieve instance creation from KClass on non-JVM platforms?
a

Arkadii Ivanov

07/24/2020, 5:38 PM
I'm not sure but I would think it is not possible.
s

Sam

07/24/2020, 5:56 PM
Reflection in native is mostly non-existent. Projects like kotlinx-serialization use annotations and code generation to get the job done on iOS.
a

Alberto

07/24/2020, 5:57 PM
Got it, thanks
k

kpgalligan

07/24/2020, 7:51 PM
Kotlin/Native is a lot more like Swift than the JVM in that respect. Very little reflection and dynamic interaction with classes.
s

spierce7

07/24/2020, 7:52 PM
@Alberto Reflection is a form of meta programming. You may find that you can get similar results with Compiler Plugins, another form of meta programming that will be supported (eventually) on all Kotlin platforms.
a

Alberto

07/24/2020, 7:53 PM
Got it, I was trying to implement something like a component registry / service locator to be used across Android/iOS but sounds like may want to use something different, perhaps like DI via Koin, unless there's other recommendations
s

Sam

07/24/2020, 8:35 PM
Koin builds its registry up with closures that construct objects rather than reflection.
z

zsperske

07/24/2020, 8:47 PM
I've had a good experience with Koin, though correct me if I'm wrong @Sam. I thought Koin does call
getKClass
somewhere internally
i ended up wrapping any swift objects that were passed into Koin with a kotlin object
s

Sam

07/24/2020, 8:48 PM
My experience with it is only on Android. On iOS I use a Coordinator to build up my dependency graph and pass it into the ViewControllers/ViewModels.
k

kpgalligan

07/24/2020, 8:50 PM
I wrote the koin native implementation! It does use kclass, but reflection is just nowhere near as dynamic on native. I forget the details at the moment on how it resolves, but it’s different than the jvm for sure.
😍 1
👍 1
r

russhwolf

07/24/2020, 8:52 PM
You actually can pass Swift things to Koin if you cast to
Any
first to avoid KClass issues, but then you lose type safety and need to use qualifiers to manually distinguish things. Much cleaner if you wrap in a Kotlin object.
m

Michal Harakal

07/27/2020, 5:47 AM
@zsperske could you pls explain more in detail how do you “wrap swift objects into kotlin object” ?
z

zsperske

07/27/2020, 1:55 PM
via delegation
say you have a swift class
DatabaseDriverIos
that implements an interface you defined in kotlin called
DatabaseDriver
which you want to provide to Koin when your app starts
you can write a kotlin class in your iOSMain code that looks like
Copy code
class DatabaseDriverWrapper(private val databaseDriverImpl) : DatabaseDriver by databaseDriverImpl
👍 1
when you're about to feed Koin the classes it needs, you construct that wrapper and feed it in an instance of
DatabaseDriverIos
this was all actually suggested to me by @russhwolf (thanks again!), please correct me if I've overcomplicated it
r

russhwolf

07/27/2020, 3:36 PM
For that specific use-case you might be overcomplicating things. If
DatabaseDriver
is a Kotlin type then as long as you cast to that in your Koin code you probably don't need the wrapper. eg you could define
Copy code
fun configureKoin(databaseDriver: DatabaseDriver) {
  startKoin(modules(module {
    ...
    single { databaseDriver }
  }))
}
and then call
configureKoin()
from Swift. But if
DatabaseDriverIos
doesn't implement a Kotlin interface then you'd want a wrapper like
class DatabaseDriverWrapper(val databaseDriverIos: DatabaseDriverIos)
to be able to bind it to Koin. (sorry to take this thread off the rails)
👍 2
m

Michal Harakal

07/27/2020, 5:24 PM
Thanks for you answers @zsperske and @russhwolf. In my particular case I need to use AWS native libs with “nice” callback APIs so I’ve already gave up on putting them in the common part. My current implementation use technique “ServiceRegistry” with lambdas in the same manner as “DroidconApp”. Works fine, but I like the idea of wrapper seeding in iosMain, so I will give it an another try. Just for the sake of consinstency in an usage of Koin
11 Views