ตั้งค่า 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-core:1.3.0")
  // The Preferences DataStore library
  implementation("androidx.datastore:datastore-preferences-core:1.3.0")
}

กำหนดคลาส DataStore

คุณสามารถกำหนดคลาส DataStore ด้วย DataStoreFactory ภายในแหล่งที่มาทั่วไปของโมดูล KMP ที่แชร์ได้ การวางคลาสเหล่านี้ในแหล่งที่มาทั่วไปจะช่วยให้แชร์คลาสเหล่านี้ในแพลตฟอร์มเป้าหมายทั้งหมดได้ คุณสามารถใช้การประกาศ 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

หากต้องการสร้างอินสแตนซ์ DataStore ใน Android คุณต้องมี 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 (เดสก์ท็อป)

หากต้องการสร้างอินสแตนซ์ DataStore ใน JVM (เดสก์ท็อป) ให้ระบุเส้นทางโดยใช้ Java หรือ 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) }
    )
)