Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Koin Initialization Issue with Kotlin Multiplatform Mobile (KMM) on iOS #2016

Open
BirdUshenin opened this issue Oct 6, 2024 · 1 comment
Labels
question Usage question

Comments

@BirdUshenin
Copy link

BirdUshenin commented Oct 6, 2024

Hello!
I encountered a problem while integrating Koin for dependency injection in a Kotlin Multiplatform Mobile (KMM) project with modularization. Specifically, the issue arises on iOS when trying to inject some class in Helper class.

Scenario:
I have the main app gradle module where I start Koin:

HelperIosKoin.kt:

fun initKoin() {
   startKoin {
       modules(geoPositionModule())
   }
}

Also, I have a geoposition gradle module which is responsible for providing geo-location data. This gradle module has some GeoPositionProvider class and the corresponding Koin module:

GeoPositionProvider.kt:

class GeoPositionProvider {


   fun getPosition(): String = "My current geo is (0,0)"


}

I add GeoPositionProvider class to the DI Graph this way:

GeoPositionModule.kt:

fun geoPositionModule() = module {
   single { GeoPositionProvider() }
}

In iOS part I have the following code to initialise Koin in the project:

iOSApp.swift:

@main
struct iOSApp: App {


   init() {
       HelperIosKoinKt.doInitKoin()
   }


   var body: some Scene {
       WindowGroup {
           ContentView()
       }
   }
}

And I want to inject my GeoPositionProvider class in the ContentView file. To do so, I have the corresponding Helper class. My helper class looks like this:

GeoPositionProviderHelper.kt:

class GeoPositionProviderHelper: KoinComponent {

   private val geoPositionProvider: GeoPositionProvider by inject()

   fun getGeo(): String = geoPositionProvider.getPosition()

}

ContentView.swift:

struct ContentView: View {
   let geo = GeoPositionProviderHelper().getGeo()


   var body: some View {
      Text(geo)
   }
}

struct ContentView_Previews: PreviewProvider {
   static var previews: some View {
      ContentView()
   }
}

The issue:
If I locate my GeoPositionProviderHelper class in the main app gradle module, in the same module where I start Koin, everything works fine.

But if I locate GeoPositionProviderHelper class in the geoposition gradle module, in the same module where GeoPositionProvider class is stored and where I have geoPositionModule Koin module, I get the app crash with the following exception:
kotlin.IllegalStateException: KoinApplication has not been started

Could you please tell me what is the cause of this problem? Is it possible to have Helper class not in the app gradle module, but in another gradle module?

Environment:
Kotlin version: [kotlin = "2.0.20"]
Koin version: [koin = "3.6.0-Beta4"]

Let me know if you need any additional details or steps to reproduce this issue. Thanks!

@arnaudgiuliani arnaudgiuliani added the question Usage question label Nov 18, 2024
@arnaudgiuliani
Copy link
Member

From what I see here, you could have a race condition because of your usage of KoinComponent. It will evaluate your Koin context to prepare your lazy field.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Usage question
Projects
None yet
Development

No branches or pull requests

2 participants