DataStore (Kotlin Multiplatform)

The DataStore library stores data asynchronously, consistently, and transactionally, overcoming some of the drawbacks of SharedPreferences. This page focuses on creating DataStore in Kotlin Multiplatform (KMP) projects. For more information on DataStore, see the primary documentation for DataStore and official samples.

Setting up dependencies

DataStore supports KMP in versions 1.1.0 and higher.

To set up DataStore in your KMP project, add the dependencies for the artifacts in the build.gradle.kts file for your module:

  • androidx.datastore:datastore - DataStore library
  • androidx.datastore:datastore-preferences - The Preferences DataStore library

Define the DataStore classes

You can define the DataStore class with DataStoreFactory inside the common source of your shared KMP module. Placing these classes in common sources allows them to be shared across all target platforms. You can use actual and expect declarations to create platform-specific implementations.

Create the DataStore instance

You need to define how to instantiate the DataStore object on each platform. This is the only part of the API that is required to be in the specific platform source sets due to the differences in file system APIs.

Common

// shared/src/androidMain/kotlin/createDataStore.kt

/**
 * Gets the singleton DataStore instance, creating it if necessary.
 */
fun createDataStore(producePath: () -> String): DataStore<Preferences> =
        PreferenceDataStoreFactory.createWithPath(
            produceFile = { producePath().toPath() }
        )

internal const val dataStoreFileName = "dice.preferences_pb"

Android

To create the DataStore instance, you need a Context along with the file path.

// shared/src/androidMain/kotlin/createDataStore.android.kt

fun createDataStore(context: Context): DataStore<Preferences> = createDataStore(
    producePath = { context.filesDir.resolve(dataStoreFileName).absolutePath }
)

iOS

To create the DataStore instance, you need a database factory along with the database path.

// shared/src/iosMain/kotlin/createDataStore.kt

fun createDataStore(): DataStore<Preferences> = createDataStore(
    producePath = {
        val documentDirectory: NSURL? = NSFileManager.defaultManager.URLForDirectory(
            directory = NSDocumentDirectory,
            inDomain = NSUserDomainMask,
            appropriateForURL = null,
            create = false,
            error = null,
        )
        requireNotNull(documentDirectory).path + "/$dataStoreFileName"
    }
)