// Depending on the platform:// jvm: DataStoreStorage.create(folder = File(System.getProperty("user.dir")), name = "settings")// android/iOS: DataStoreStorage.create(name = "preferences")objectPreferences:SettingsModel(DataStoreStorage.create(name="preferences")){// main data typesvalsomeStringbystringPref("value")valsomeBoolbyboolPref(false)valsomeIntbyintPref(123)valsomeLongbyintPref(123L)valsomeFloatbyintPref(123f)valsomeDoublebyintPref(123.0)// enumvalsomeEnumbyenumPref(Enum.Value1)// customvalsomeCustomClass1byanyStringPref(TestClass.CONVERTER,TestClass())// converts TestClass to a string and saves this stringvalsomeCustomClass2byanyIntPref(TestClass.CONVERTER,TestClass())// converts TestClass to an int and saves this intvalsomeCustomClass3byanyLongPref(TestClass.CONVERTER,TestClass())// converts TestClass to a long and saves this long// setsvalsomeStringSetbystringSetPref(setOf("a"))valsomeIntSetbyintSetPref(setOf(1))valsomeLongSetbylongSetPref(setOf(1L))valsomeFloatSetbyfloatSetPref(setOf(1f))valsomeDoubleSetbydoubleSetPref(setOf(1.0))// NULLABLE vs NON NULLABLEvalnonNullableStringbystringPref()valnullableStringbynullableStringPref()valnonNullableIntbyintPref()valnullableIntbynullableIntPref()valnonNullableFloatbyfloatPref()valnullableFloatbynullableFloatPref()valnonNullableDoublebydoublePref()valnullableDoublebynullableDoublePref()valnonNullableLongbylongPref()valnullableLongbynullableLongPref()valnonNullableBoolbyboolPref()valnullableBoolbynullableBoolPref()// customvalsomeCustomClass4bynullableAnyStringPref(TestClass.CONVERTER,TestClass())valsomeCustomClass5bynullableAnyIntPref(TestClass.CONVERTER,TestClass())valsomeCustomClass6bynullableAnyLongPref(TestClass.CONVERTER,TestClass())}
2a) Use the SettingsModel in plain kotlin (flows + suspending functions)#
// 1) get a flowvalflow=Preferences.someString.flow// 2) read/update values by suspend functionsscope.launch(Dispatchers.IO){valvalue=Preferences.someInt.read()Preferences.someInt.update(value+1)}
2b) Use the SettingsModel in views (e.g. with Lifecycle Scope)#
// 1) simply observe a settingPreferences.someString.observe(lifecycleScope){L.d{"someString = $it"}}// 2) direct read (not recommended if not necessary but may be useful in many cases)// => simply returns read() in a blocking way)valname=Preferences.someString.value// 3) observe a setting oncePreferences.someString.observeOnce(lifecycleScope){L.d{"someString = $it"}}// 4) observe ALL settingsPreferences.changes.onEach{L.d{"[ALL SETTINGS OBSERVER] Setting '${it.setting.key}' changed its value to ${it.value}"}}.launchIn(lifecycleScope)// 5) observe SOME settingsPreferences.changes.filter{it.setting==Preferences.someString||it.setting==Preferences.someBool}.onEach{L.d{"[SOME SETTINGS OBSERVER] Setting '${it.setting.key}' changed its value to ${it.value}"}}.launchIn(lifecycleScope)// 6) read multiple settings in a suspending waylifecycleScope.launch(Dispatchers.IO){valsomeString=Preferences.someString.read()valsomeBool=Preferences.someBool.read()}
valname=Preferences.someString.collectAsState()valname=Preferences.someString.collectAsStateWithLifecycle()// simply use the state inside your composables, the state will change whenever the setting behind it will changevalname=Preferences.someString.asMutableState()// simple use and even update the state now