我有一个实现数据存储的 Compose 多平台项目。我使用多平台数据存储作为参考。我在注入数据存储时遇到问题。
常见主要:
fun getDataStore(producePath: () -> String): DataStore<Preferences> =
synchronized(lock) {
if (::dataStore.isInitialized) {
dataStore
} else {
PreferenceDataStoreFactory.createWithPath(produceFile = { producePath().toPath() })
.also { dataStore = it }
}
}
internal const val dataStoreFileName = "app.preferences_pb"
android主要:
fun getDataStore(context: Context): DataStore<Preferences> = getDataStore(
producePath = { context.filesDir.resolve(dataStoreFileName).absolutePath }
)
iOS 主要 :
@OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
fun createDataStore(): DataStore<Preferences> = getDataStore(
producePath = {
val documentDirectory: NSURL? = NSFileManager.defaultManager.URLForDirectory(
directory = NSDocumentDirectory,
inDomain = NSUserDomainMask,
appropriateForURL = null,
create = false,
error = null,
)
requireNotNull(documentDirectory).path + "/$dataStoreFileName"
}
)
我有一个访问数据存储的类
class GameskiiSettingRepository(
private val dataStore: DataStore<Preferences>
)
我不知道如何注入该数据存储,并且不断收到此错误
Caused by: org.koin.core.error.NoBeanDefFoundException: No definition
found for type 'androidx.datastore.core.DataStore'. Check your Modules
configuration and add missing type and/or qualifier!
我通过声明一个实例化数据存储的
expect actual
koin 模块解决了这个问题。您的 getDataStore
签名有点不同,但这也应该适合您。
在
preferenceModule
中声明 commonMain
:
// commonMain
expect val preferenceModule: Module
在
actual
和 preferenceModule
中定义 androidMain
的 iosMain
实现:
// androidMain
actual val preferenceModule: Module = module {
single { createDataStore(androidContext()) }
}
// iosMain
actual val preferenceModule: Module = module {
// Here you don't need to pass null
single { createDataStore(null) }
}
将此模块添加到
Android
和 iOS
的 Koin 初始值设定项中:
// androidMain
actual class KoinInitializer(
private val context: Context,
) {
actual fun init() {
startKoin {
androidContext(context)
androidLogger()
modules(
appModule, viewModelModule, preferenceModule
)
}
}
}
// iosMain
actual class KoinInitializer {
actual fun init() {
startKoin {
modules(appModule, viewModelModule, preferenceModule)
}
}
}
最后,提供
GameskiiSettingRepository
依赖项,如下所示:
single { GameskiiSettingRepository(get()) }
现在您可以将此 Repo 注入到 Viewmodel 中。