hello everyone. we are developing a kotlin multipl...
# multiplatform
e
hello everyone. we are developing a kotlin multiplatform app using the template in here . We are targeting windows, ios & android, and we are using sqldelight for database and koin for DI. In sqldelight, as stated in it's documentation , we need a "DriverFactory" class that is responsible for creating the sql driver for each platform. to achieve this, in commonMain we have:
Copy code
import com.example.Database

expect class DriverFactory {
  fun createDriver(): SqlDriver
}

fun createDatabase(driverFactory: DriverFactory): Database {
  val driver = driverFactory.createDriver()
  val database = Database(driver)

  // Do more work with the database (see below).
}
in androidMain:
Copy code
actual class DriverFactory(private val context: Context) {
  actual fun createDriver(): SqlDriver {
    return AndroidSqliteDriver(Database.Schema, context, "test.db") 
  }
}
in jvmMain:
Copy code
actual class DriverFactory {
  actual fun createDriver(): SqlDriver {
    val driver: SqlDriver = JdbcSqliteDriver(JdbcSqliteDriver.IN_MEMORY)
    Database.Schema.create(driver)
    return driver
  }
}
as you can see, the constructor for these classes are different. when I implement the exact same thing stated in sqldelight documentation, I get this compile error : Actual class 'DriverFactory' has no corresponding members for expected class members: public constructor DriverFactory() defined in nikted.fitting.compose.kmp.platform.DriverFactory The following declaration is incompatible because number of value parameters is different: public constructor DriverFactory(context: Context) defined in nikted.fitting.compose.kmp.platform.DriverFactory I have tried putting aside koin ( only for this class ) and using the direct singleton instance of Android like this:
Copy code
actual class DriverFactory {
    val context = AndroidApp.INSTANCE.applicationContext
    actual fun createDriver(): SqlDriver {
        return AndroidSqliteDriver(FittingDb.Schema, context, "FittingDb.db")
    }
}
but it will lead to other problems like when testing the application on android. I would really appreciate it if someone could show me a way that I can resolve this dependency from koin instead of creating a direct instance. thanks
m
This may not be the best was to do it but it has worked for me. This is my Android implementation of the factory.
Copy code
actual class DatabaseDriverFactoryImpl actual constructor() : DatabaseDriverFactory {

    private lateinit var activity: ComponentActivity

    fun init(activity: ComponentActivity) {
        this.activity = activity
    }

    override fun createDatabaseDriver(dbFilePath: String): SqlDriver {
        return AndroidSqliteDriver(AIPDatabase.Schema, activity.applicationContext, dbFilePath)
    }

}
As you can see I have added an init method to it. I call this when the model is initialized from the Activity like this:
Copy code
val databaseDriverFactory: DatabaseDriverFactory by inject()
(databaseDriverFactory as DatabaseDriverFactoryImpl).init(activity)
d
Create the
DriverFactory
as part of a
platformModule
that each platform defines. You can see a concrete example of this kind of approach in https://github.com/touchlab/KaMPKit. • Have the common Koin module leverage the platform module: https://github.com/touchlab/KaMPKit/blob/main/shared/src/commonMain/kotlin/co/touchlab/kampkit/Koin.kt#L24 - Note that the
expect
is here at the end of that file: https://github.com/touchlab/KaMPKit/blob/main/shared/src/commonMain/kotlin/co/touchlab/kampkit/Koin.kt#L87 • Create the Android platformModule in androidMain: https://github.com/touchlab/KaMPKit/blob/main/shared/src/androidMain/kotlin/co/touchlab/kampkit/KoinAndroid.kt#L12 • Create the iOS platformModule in iOSMain: https://github.com/touchlab/KaMPKit/blob/main/shared/src/iosMain/kotlin/co/touchlab/kampkit/KoinIOS.kt#L30
1
plus1 1