Is anyone here using Koin in their Kotlin Multipla...
# koin
z
Is anyone here using Koin in their Kotlin Multiplatform project? How are you feeding your swift classes into Koin from your iOS app?
s
From the
ios
Swift/Obj-C code, or from the
iosMain
shared code?
z
From the iOS Swift/Obj-C code
s
Ah… “swift classes” 🙂 Through interfaces/protocols:
When initializing Koin, we call a method into the iosMain kotlin-code (eg
fun initKoin(….)
) and the
initKoin
has parameter(s) defined as `interface`s. When calling
initKoin(…)
from Swift (these `interface`s are represented as protocols) provide implementations of these protocol(s) as input to the call to
initKoin(…)
z
ahhh
something like this?
Copy code
fun init(eventDataSource: EventDataSource) {
        koin = initKoin {
            module { 
                single { eventDataSource }
            }
        }
    }
s
Yup.
z
makes sense, thank you!
what project are you using KMP on if you don't mind me asking?
s
Try to do as much as possible in the
shared
module of your project. But if all else fails, do this passing of protocol-implementations when init-ing the Koin instance.
We use it for an internal ‘try-it-out’/evaluation project.
z
yeah I'm starting to doubt this path I'm taking, if I wanted to use something like Firebase in my
iOSMain
code, I can pull those swift/obj-c classes into my kotlin as well right?
s
As long as they implemented a protocol that was defined by an interface in the
shared
module, then yes.
We favor
interface
(protocol) and implementations of them over
expect
and
actual
. We reserve
expect
and
actual
for specific use-cases only.
z
what helps you make the decision between
expect/actual
and
interface
?
s
expect/actual
for simple top-level functions, top-level vals, etc. Otherwise `interface`s. However, if the
interface
implementations require constant down-casting on the
app
or
ios
side of the code and there is truly only one implementation for each target (one for
app
, one for
ios
), then you may want to consider using
expect/actual
again.
^^^ These are our findings so far… other folks may disagree 🙂
z
i'll keep those in mind, I appreciate your time Anton! thanks
r
Something to watch out for when doing this: Koin tries to grab the
KClass
internally of anything in the dependency graph. If you want to add a Swift/Obj-C type to the Koin graph, it will fail. You can work around it by casting to
Any
and using qualifiers, but it gets syntactically pretty ugly.
Most of the time you probably won't need to do that, though. You probably really want Kotlin types in your Koin graph, even if you have to pass something from Swift to construct it.
👍 1
z
i.e. composing a kotlin type with a swift type as a field? so that Koin provides a kotlin object, but that object delegates its calls to a swift object?
r
right. Like if you’re using Multiplatform Settings, you might want to pass
NSUserDefaults
from Swift, but it’s messy to bind that directly to Koin rather than constructing
AppleSettings
and passing that to Koin.
z
makes sense, another question if you don't mind. this one is a bit more broad so my apologies if its tough to answer. is there any place to learn more about cinterop? i've been referring to the kotlin lang docs, as well as a couple github repos (including one your company built, firestoreKMP) and I'm still pretty lost but it feels like it may be the better route in my case
r
I don’t know much better cinterop docs than the official ones. I agree it can be tough to wrap your head around, especially coming from the JVM world and not being used to linker flags. You could try asking in #kotlin-native if anybody knows a good blog post or something.
👍 1
z
fair enough, thanks for the wisdom!