// In commonMain - DataStore interfaceinterfaceUserPreferences{valuserData:Flow<UserData>suspendfunupdateUsername(name:String)suspendfunupdateEmail(email:String)suspendfunclearData()}// In commonMain - Data modeldataclassUserData(valusername:String="",valemail:String="",valisLoggedIn:Boolean=false)
在 KMP 项目中设置数据存储
要将 DataStore 集成到你的 KMP 项目中,你需要正确配置构建文件。以下是分步指南:
1. 在共享模块中配置 build.gradle.kts 文件
123456789101112131415161718192021222324
plugins{kotlin("multiplatform")id("com.android.library")id("com.google.devtools.ksp")version"2.1.20-2.0.1"// For Proto DataStore}kotlin{androidTarget()iosX64()iosArm64()iosSimulatorArm64()sourceSets{valcommonMainbygetting{dependencies{// For Preferences DataStoreimplementation("androidx.datastore:datastore-preferences-core:1.1.0")// For coroutinesimplementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3")}}}}
// In commonMainclassUserPreferencesRepository(privatevaldataStore:PreferencesDataStore){//定义preferences的键privateobjectPreferenceKeys{valUSERNAME=stringPreferencesKey("username")valEMAIL=stringPreferencesKey("email")valIS_LOGGED_IN=booleanPreferencesKey("is_logged_in")}// Get user data as a FlowvaluserData:Flow<UserData>=dataStore.data.map{preferences->UserData(username=preferences[PreferenceKeys.USERNAME]?:"",email=preferences[PreferenceKeys.EMAIL]?:"",isLoggedIn=preferences[PreferenceKeys.IS_LOGGED_IN]?:false)}// Update usernamesuspendfunupdateUsername(name:String){dataStore.updateData{preferences->preferences.toMutablePreferences().apply{this[PreferenceKeys.USERNAME]=name}}}// Update emailsuspendfunupdateEmail(email:String){dataStore.updateData{preferences->preferences.toMutablePreferences().apply{this[PreferenceKeys.EMAIL]=email}}}// Set login statussuspendfunsetLoggedIn(isLoggedIn:Boolean){dataStore.updateData{preferences->preferences.toMutablePreferences().apply{this[PreferenceKeys.IS_LOGGED_IN]=isLoggedIn}}}// Clear all datasuspendfunclearData(){dataStore.updateData{preferences->preferences.toMutablePreferences().apply{remove(PreferenceKeys.USERNAME)remove(PreferenceKeys.EMAIL)remove(PreferenceKeys.IS_LOGGED_IN)}}}}// In commonMain - ViewModel or PresenterclassUserViewModel(privatevaluserPreferencesRepository:UserPreferencesRepository){valuserData:Flow<UserData>=userPreferencesRepository.userDatasuspendfunupdateUserProfile(username:String,email:String){if(username.isNotBlank()){userPreferencesRepository.updateUsername(username)}if(email.isNotBlank()){userPreferencesRepository.updateEmail(email)}}suspendfunlogin(){userPreferencesRepository.setLoggedIn(true)}suspendfunlogout(){userPreferencesRepository.setLoggedIn(false)}suspendfunclearUserData(){userPreferencesRepository.clearData()}}
// In commonMain - 创建序列化器classUserPreferencesSerializer:Serializer<UserPreferences>{overridevaldefaultValue:UserPreferences=UserPreferences.getDefaultInstance()overridesuspendfunreadFrom(input:InputStream):UserPreferences{returnUserPreferences.parseFrom(input)}overridesuspendfunwriteTo(t:UserPreferences,output:OutputStream){t.writeTo(output)}}// Proto DataStore 的平台特定实现
2.数据迁移
123456789101112
// In androidMain - 从 SharedPreferences 迁移到 DataStorevaldataStore=context.createDataStore(name="user_preferences",produceMigrations={context->listOf(SharedPreferencesMigration(context=context,sharedPreferencesName="legacy_preferences"))})
3.处理异常
1234567891011121314151617
// In commonMain - 数据操作过程中的异常处理valuserData=dataStore.data.catch{exception->// 处理异常(例如数据损坏)if(exceptionisIOException){emit(emptyPreferences())}else{throwexception}}.map{preferences->// Map preferences to your data modelUserData(username=preferences[USERNAME]?:"",email=preferences[EMAIL]?:"")}