Hello everyone. I am building a KMM project and am using `Koin` for DI. Everything works fine on :an...
d
Hello everyone. I am building a KMM project and am using
Koin
for DI. Everything works fine on 🤖 I just want to get the repository inside the viewModel, Screen or whichever class. There I use
Copy code
let repository: Repository = Koin.instance.get()
In iOSMain I got the following bridge in file called
KoinIOS.kt
Copy code
import com.russhwolf.settings.NSUserDefaultsSettings
import com.russhwolf.settings.Settings
import kotlinx.cinterop.ObjCClass
import kotlinx.cinterop.getOriginalKotlinClass
import org.koin.core.Koin
import org.koin.core.KoinApplication
import org.koin.core.parameter.parametersOf
import org.koin.core.qualifier.Qualifier
import org.koin.dsl.module
import platform.Foundation.NSUserDefaults

object KoinIOS {
    fun initialize(
        userDefaults: NSUserDefaults,
    ): KoinApplication = initKoin(
        appModule = module {
            single<Settings> {
                NSUserDefaultsSettings(userDefaults)
            }
        }
    ) // swift doesn't bridge Kotlin functions with default parameters. This functions is to compensate for that limitation
}

fun Koin.get(objCClass: ObjCClass): Any {
    val kClazz = getOriginalKotlinClass(objCClass)!!
    return get(kClazz, null, null)
}

fun Koin.get(objCClass: ObjCClass, qualifier: Qualifier?, parameter: Any): Any {
    val kClazz = getOriginalKotlinClass(objCClass)!!
    return get(kClazz, qualifier) { parametersOf(parameter) }
}

actual val platformModule = module {}
I have
Koin.swift
file on iOS side in order to adapt it on
iOSApp
Copy code
import shared

final class Koin {
  private var core: Koin_coreKoin?

  static let instance = Koin()

  static func start() {
    if instance.core == nil {
      let app = KoinIOS.shared.initialize(
        userDefaults: UserDefaults.standard
      )
      instance.core = app.koin
    }
    if instance.core == nil {
      fatalError("Can't initialize Koin.")
    }
  }

  private init() {
  }

  func get<T: AnyObject>() -> T {
    guard let core = core else {
      fatalError("You should call `start()` before using \(#function)")
    }

    guard let result = core.get(objCClass: T.self) as? T else {
      fatalError("Koin can't provide an instance of type: \(T.self)")
    }

    return result
  }
}
Error I am getting at the moment is when I call
Koin.instance.get()
and then it tries to execute
Copy code
guard let result = core.get(objCClass: T.self) as? T else {fatalError("Koin can't provide an instance of type: \(T.self)")  }
Thread 1: EXC_BAD_ACCESS (code=1, address=0x310)
Someone please help, I don’t know why this is happening
k
Maybe it’s from this line
val kClazz = getOriginalKotlinClass(objCClass)!!
force unwrapping
d
Thanks Kevin, any idea how can I debug/check this? It kinda gives me nothing. I assume it just finds the error in compiled machine code sad panda
when returning null there still doesn’t work and gives the same error
Copy code
fun Koin.get(objCClass: ObjCClass): Any? {
    val kClazz = getOriginalKotlinClass(objCClass)
    return kClazz?.let { get(it, null, null) }
}
k
Theres an XCode plugin that helps with debugging https://github.com/touchlab/xcode-kotlin
d
Thank you Kevin, I will check it out