|
| 1 | +--- |
| 2 | +title: 'DataStore' |
| 3 | +description: 'Simplify DataStore setup in Kotlin Multiplatform' |
| 4 | +--- |
| 5 | + |
| 6 | +Setting up [DataStore](https://developer.android.com/kotlin/multiplatform/datastore) in Kotlin Multiplatform typically requires platform-specific code for each target. FileKit simplifies this by providing a unified path API. |
| 7 | + |
| 8 | +## The Problem |
| 9 | + |
| 10 | +The [official DataStore setup](https://developer.android.com/kotlin/multiplatform/datastore) requires `expect`/`actual` declarations with platform-specific implementations: |
| 11 | + |
| 12 | +- **Android** needs `Context.filesDir` |
| 13 | +- **iOS** needs `NSDocumentDirectory` |
| 14 | +- **JVM** needs `System.getProperty("java.io.tmpdir")` or a custom path |
| 15 | + |
| 16 | +This means writing and maintaining code in `androidMain`, `iosMain`, and `jvmMain` source sets. |
| 17 | + |
| 18 | +## The Solution |
| 19 | + |
| 20 | +With FileKit, you can define everything in `commonMain`: |
| 21 | + |
| 22 | +```kotlin |
| 23 | +import androidx.datastore.core.DataStore |
| 24 | +import androidx.datastore.preferences.core.Preferences |
| 25 | +import androidx.datastore.preferences.core.PreferenceDataStoreFactory |
| 26 | +import io.github.vinceglb.filekit.FileKit |
| 27 | +import io.github.vinceglb.filekit.databasesDir |
| 28 | +import kotlinx.io.files.Path |
| 29 | + |
| 30 | +fun createDataStore(fileName: String = "settings.preferences_pb"): DataStore<Preferences> = |
| 31 | + PreferenceDataStoreFactory.createWithPath { |
| 32 | + FileKit.databasesDir.resolve(fileName).path.toPath() |
| 33 | + } |
| 34 | +``` |
| 35 | + |
| 36 | +That's it! No platform-specific code needed. |
| 37 | + |
| 38 | +## Complete Example |
| 39 | + |
| 40 | +Here's a complete setup for a preferences manager: |
| 41 | + |
| 42 | +```kotlin |
| 43 | +import androidx.datastore.core.DataStore |
| 44 | +import androidx.datastore.preferences.core.Preferences |
| 45 | +import androidx.datastore.preferences.core.booleanPreferencesKey |
| 46 | +import androidx.datastore.preferences.core.edit |
| 47 | +import androidx.datastore.preferences.core.PreferenceDataStoreFactory |
| 48 | +import io.github.vinceglb.filekit.FileKit |
| 49 | +import io.github.vinceglb.filekit.databasesDir |
| 50 | +import kotlinx.coroutines.flow.Flow |
| 51 | +import kotlinx.coroutines.flow.map |
| 52 | + |
| 53 | +object AppPreferences { |
| 54 | + private val dataStore: DataStore<Preferences> = PreferenceDataStoreFactory.createWithPath { |
| 55 | + FileKit.databasesDir.resolve("app.preferences_pb").path.toPath() |
| 56 | + } |
| 57 | + |
| 58 | + private val DARK_MODE_KEY = booleanPreferencesKey("dark_mode") |
| 59 | + |
| 60 | + val darkMode: Flow<Boolean> = dataStore.data.map { preferences -> |
| 61 | + preferences[DARK_MODE_KEY] ?: false |
| 62 | + } |
| 63 | + |
| 64 | + suspend fun setDarkMode(enabled: Boolean) { |
| 65 | + dataStore.edit { preferences -> |
| 66 | + preferences[DARK_MODE_KEY] = enabled |
| 67 | + } |
| 68 | + } |
| 69 | +} |
| 70 | +``` |
| 71 | + |
| 72 | +## Why `databasesDir`? |
| 73 | + |
| 74 | +`FileKit.databasesDir` returns a platform-appropriate location for persistent data: |
| 75 | + |
| 76 | +| Platform | Location | |
| 77 | +|----------|----------| |
| 78 | +| Android | App's internal databases directory | |
| 79 | +| iOS | `NSDocumentDirectory` | |
| 80 | +| macOS | `~/Library/Application Support/{bundle-id}` | |
| 81 | +| JVM | User's app data directory | |
| 82 | + |
| 83 | +This ensures your preferences are stored in a safe, persistent location on each platform. |
| 84 | + |
| 85 | +## Dependencies |
| 86 | + |
| 87 | +Add the DataStore dependencies alongside FileKit Core: |
| 88 | + |
| 89 | +```kotlin |
| 90 | +commonMain.dependencies { |
| 91 | + // FileKit Core |
| 92 | + implementation("io.github.vinceglb:filekit-core:<version>") |
| 93 | + |
| 94 | + // DataStore |
| 95 | + implementation("androidx.datastore:datastore-preferences:<version>") |
| 96 | +} |
| 97 | +``` |
0 commit comments