ตั้งค่า DataStore สำหรับ KMP

ไลบรารี DataStore จัดเก็บข้อมูลแบบไม่พร้อมกัน สอดคล้องกัน และ แบบธุรกรรม ซึ่งช่วยแก้ข้อเสียบางอย่างของ SharedPreferences หน้านี้มุ่งเน้นการสร้าง DataStore ในโปรเจ็กต์ Kotlin Multiplatform (KMP) ดูข้อมูลเพิ่มเติมเกี่ยวกับ DataStore ได้ที่เอกสารประกอบหลักสำหรับ DataStore และตัวอย่างอย่างเป็นทางการ

ตั้งค่าทรัพยากร Dependency

หากต้องการตั้งค่า DataStore ในโปรเจ็กต์ KMP ให้เพิ่มทรัพยากร Dependency สำหรับอาร์ติแฟกต์ ในไฟล์ build.gradle.kts ของโมดูล

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

กำหนดคลาส DataStore

คุณสามารถกำหนดDataStore class ที่มี DataStoreFactory ภายในแหล่งที่มาทั่วไปของโมดูล KMP ที่แชร์ การวางคลาสเหล่านี้ในแหล่งที่มาทั่วไปจะช่วยให้แชร์คลาสในแพลตฟอร์มเป้าหมายทั้งหมดได้ คุณสามารถใช้ประกาศ actual และ expect เพื่อสร้างการติดตั้งใช้งานเฉพาะแพลตฟอร์มได้

สร้างอินสแตนซ์ DataStore

คุณต้องกำหนดวิธีสร้างออบเจ็กต์ DataStore ในแต่ละแพลตฟอร์ม นี่เป็นส่วนเดียวของ API ที่ต้องอยู่ในชุดซอร์สของแพลตฟอร์มที่เฉพาะเจาะจงเนื่องจากความแตกต่างใน File System 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

หากต้องการสร้างอินสแตนซ์ DataStore ใน Android คุณต้องมี Context พร้อมกับเส้นทาง

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

fun createDataStore(): DataStore<Preferences> = createDataStore(
    storage = FileStorage(
        serializer = PreferencesSerializer,
        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 (เดสก์ท็อป)

หากต้องการสร้างอินสแตนซ์ DataStore ใน JVM (เดสก์ท็อป) ให้ระบุเส้นทางโดยใช้ Java หรือ Kotlin API

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

fun createDataStore(): DataStore<Preferences> = createDataStore(
    storage = FileStorage(
        serializer = PreferencesSerializer,
        produceFile = { File(System.getProperty("java.io.tmpdir"), dataStoreFileName) }
    )
)
แทนได้