Thread
#multiplatform
    a

    Alberto

    2 years ago
    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.
    Arkadii Ivanov

    Arkadii Ivanov

    2 years ago
    a

    Alberto

    2 years ago
    interesting. Is there any example on how to achieve instance creation from KClass on non-JVM platforms?
    Arkadii Ivanov

    Arkadii Ivanov

    2 years ago
    I'm not sure but I would think it is not possible.
    s

    Sam

    2 years ago
    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

    2 years ago
    Got it, thanks
    kpgalligan

    kpgalligan

    2 years ago
    Kotlin/Native is a lot more like Swift than the JVM in that respect. Very little reflection and dynamic interaction with classes.
    spierce7

    spierce7

    2 years ago
    @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

    2 years ago
    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

    2 years ago
    Koin builds its registry up with closures that construct objects rather than reflection.
    z

    zsperske

    2 years ago
    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

    2 years ago
    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.
    kpgalligan

    kpgalligan

    2 years ago
    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.
    russhwolf

    russhwolf

    2 years ago
    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.
    Michal Harakal

    Michal Harakal

    2 years ago
    @zsperske could you pls explain more in detail how do you “wrap swift objects into kotlin object” ?
    z

    zsperske

    2 years ago
    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
    class DatabaseDriverWrapper(private val databaseDriverImpl) : DatabaseDriver by databaseDriverImpl
    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
    russhwolf

    russhwolf

    2 years ago
    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
    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)
    Michal Harakal

    Michal Harakal

    2 years ago
    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