Hello fellow koiners :wave: This is regarding mult...
# koin
j
Hello fellow koiners đź‘‹ This is regarding multiplatform, as anyone managed to do constructor injection on the Swift/iOS part? So for my specific use case, I want to inject a executor/usecase into a Swift class. The issue is this executor has a dependency and so on and forth, on Android is quite simple as we just need to declare the modules and use
by viewModel()
or wtv it suits you, you could even
inject()
but on Swift seems like we don't have access to Koin's sugar. -- Summarising: View wants to create a ViewModel <- UseCase <- Repository <- RemoteApi Note: '<-' Depends on
For some context, this is somewhat what’s happening here: • https://github.com/joreilly/PeopleInSpace/blob/master/common/src/commonMain/kotlin/com/surrus/common/repository/PeopleInSpaceRepository.kt#L30-L31 But I really wanted to do constructor injection
s
We simplified the dependency injection. We don’t use the
viewModel()
function. We have an
expect ViewModel
in the commonMain and the androidMain’s
actual
of this extends the the jetpack ViewModel, the iosMain just makes a simple
actual
out of it. Then we have in the commonMain a bunch of ViewModelFactories that act as an assisted-inject. E.g.
MyScreenViewModel
has a
MyScreenViewModelFactory
and this factory is configured through Koin (in commonMain) with the necessary dependencies. These dependencies are then used to create a
MyScreenViewModel
(this is much like the Assisted-Inject of Dagger). In Android app:
Copy code
class MyActivity : BaseActivityAndKoinComponent() {
    val factory: MyScreenViewModelFactory = inject()
    val viewModel by lazy { factory.create() }
    ...
}
In iOS:
Copy code
... 
let factory = MyScreenViewModelFactory.get()
....
let viewModel = factory.create()
To make this happen, iOS has the following extensions:
Copy code
protocol KoinInjectable: AnyObject {
    static func get(parameter: Any, qualifier: Koin_coreQualifier?) -> Self
}

extension KoinInjectable {
    /// Creates and returns an instance of `Self`
    ///
    /// If `Self` has not been registered with Koin, this will fail with an uncaught Kotlin exception.
    static func get(parameter: Any = "", qualifier: Koin_coreQualifier? = nil) -> Self {
        KoinIOS().get(objCClass: Self.self, qualifier: qualifier, parameter: parameter) as! Self
    }
}
...
extension MyScreenViewModelFactory: KoinInjectable {}
and iosMain has the kotlin function
get
defined for
object KoinOS
.
z
You could use actual/expect for defying koin modules. Then in Android you can provide it with viewModel and in iOS by using factory
j
Thank you both for your time and clarification, you did give me the pointers I need, thanks 🙏