https://kotlinlang.org logo
#multiplatform
Title
# multiplatform
r

Ryan Simon

04/27/2021, 11:58 PM
hey all, I'm running into an interesting challenge trying to setup a multi-module multiplatform project. so my goal is to have one module called
:core
and one module called
:auth
.
:auth
depends on
:core
. I also want a Koin setup where
:auth
and
:core
Koin dependencies can be initialized on each client app. this would allow me to share a network implementation from each client across both modules the problem is that when trying to setup the Koin dependencies on iOS, each module has its own version of the
Network
interface.
:auth
refers to it as
AuthCoreNetwork
and
:core
refers to it as
CoreNetwork
. with this in mind, we can't properly setup the
Network
dependency as the interfaces are incompatible this setup works fine on Android side, but not on iOS. any idea what I could do to solve for this, if anything? code sample of what I'm trying to do on the iOS side below
Copy code
func startKoin() {
    NSLog("Hi")
    let doOnStartup = { NSLog("Hello from iOS/Swift!") }
    let network = NetworkManagerImpl()
    
    Core.KoinIosKt.doInitKoinIos(doOnStartup: doOnStartup, network: network)
    Auth.KoinIosKt.doInitKoinIos(doOnStartup: doOnStartup, network: network) // doesn't work because the network instance doesn't match up
}
x

xxfast

04/28/2021, 11:31 AM
ah.. looks like we both are running to the same issue
I think
packForXCode
implicitly fix all public api of a module with the name of the module itself - causing this incompatibility
tried to used some sort of wrapper, but i still run into the same issue - the wrapped type is still scoped to the module
🙁 1
r

russhwolf

04/28/2021, 12:37 PM
If you create multiple Kotlin frameworks, they will have mutually incompatible types. If you need to pass data between different modules, it's better to do so at the Kotlin level and expose just a single top-level framework to iOS.
r

Ryan Simon

04/28/2021, 4:48 PM
gotcha, that's what it seemed like. was hoping there was some trick the community had up its sleeve. alright, not the end of the world
do you think there's still value in setting up a multi-module project then? feels like it creates more complexity than it's worth dealing with right now at this state of multiplatform @russhwolf
r

russhwolf

04/28/2021, 5:33 PM
yes I think so. Especially as your shared code grows, it can help to give it structure. It's just that the structure is more internal and doesn't get exposed to the Swift layer
r

Ryan Simon

04/28/2021, 5:36 PM
okay that makes sense, thank you. i haven't come across any suggested setups for combining multi-module kmp into a single ios framework. do you have any suggested resources for how to do that?
r

russhwolf

04/28/2021, 5:40 PM
don't know any specific examples off-hand. Generally, the framework config will look the same as for a single module, but that module has some extra dependencies on your other modules. You might need to add
export()
declarations in your framework if you need to talk to kotlin dependencies from Swift, and/or add
transitiveExports = true
. The other change is that transitive dependencies will have the module name prefixed when they reach Swift.
r

Ryan Simon

04/28/2021, 8:58 PM
that's helpful info, thank you
x

xxfast

04/29/2021, 12:28 AM
Thanks for the direction @russhwolf 🙂 In my case, i am stuck to multi-modular setup, and I was able to export library dependencies and mark them as
api
on the lib-module.
:core
Copy code
sourceSets {
    val commonMain by getting {
      dependencies {
        api(InsertKoin.koinCore)
        ...
      }
    }
}
and
:login
Copy code
ios {
    binaries {
      framework {
        export(project(":core"))
        baseName = "Login"
      }
    }
}
https://kotlinlang.org/docs/mpp-build-native-binaries.html#export-dependencies-to-binaries
r

Ryan Simon

04/29/2021, 3:24 PM
Nice, doesn't look too bad to setup
3 Views