KMP 用に DataStore を設定する

DataStore ライブラリは、データを非同期的に、一貫した形で、トランザクションとして保存するため、SharedPreferences の欠点の一部が解消されます。このページでは、Kotlin マルチプラットフォーム(KMP)プロジェクトで DataStore を作成する方法について説明します。DataStore の詳細については、DataStore のメイン ドキュメントをご覧ください。

依存関係を設定する

KMP プロジェクトで DataStore を設定するには、モジュールの build.gradle.kts ファイルにアーティファクトの依存関係を追加します。

commonMain.dependencies {
  // DataStore library
  implementation("androidx.datastore:datastore-core:1.3.0")
  // The Preferences DataStore library
  implementation("androidx.datastore:datastore-preferences-core:1.3.0")
}

DataStore クラスを定義する

DataStore クラスは、共有 KMP モジュールの共通ソース内で DataStoreFactory を使用して定義できます。これらのクラスを共通のソースに配置すると、すべてのターゲット プラットフォームで共有できます。actual 宣言と expect 宣言を使用して、プラットフォーム固有の実装を作成できます。

DataStore インスタンスを作成する

各プラットフォームで DataStore オブジェクトをインスタンス化する方法を定義する必要があります。ファイル システム API の違いにより、特定のプラットフォームのソースセットに含める必要があるのは、API のこの部分のみです。

共通

// shared/src/commonMain/kotlin/createDataStore.kt

/**
 *   Gets the singleton DataStore instance, creating it if necessary.
 */
fun createDataStore(storage: Storage<Preferences>): DataStore<Preferences> =
        DataStoreFactory.create(storage = storage)

internal const val dataStoreFileName = "dice.preferences_pb"

Android

Android で DataStore インスタンスを作成するには、パスとともに Context が必要です。

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

fun createDataStore(): DataStore<Preferences> = createDataStore(
    storage = FileStorage(
        serializer = PreferencesFileSerializer,
        produceFile = { context.filesDir.resolve(dataStoreFileName) }
    )
)

iOS

iOS では、NSDocumentDirectory からパスを取得できます。

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

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

ウェブ

ウェブで DataStore インスタンスを作成するには、WebLocalStorage または WebSessionStorage を使用します。

// shared/src/jsMain/kotlin/createDataStore.web.kt (also works for wasmJsMain)

fun createDataStore(): DataStore<Preferences> = createDataStore(
    storage = WebLocalStorage(
        serializer = PreferencesSerializer,
        name = dataStoreFileName
    )
)

JVM(デスクトップ)

JVM(デスクトップ)で DataStore インスタンスを作成するには、Java API または Kotlin API を使用してパスを指定します。

// shared/src/jvmMain/kotlin/createDataStore.desktop.kt

fun createDataStore(): DataStore<Preferences> = createDataStore(
    storage = FileStorage(
        serializer = PreferencesFileSerializer,
        produceFile = { File(System.getProperty("java.io.tmpdir"), dataStoreFileName) }
    )
)