I am currently trying to save simple data (pin and recovery email) into data store. This is so my app knows how to behave at launch. I have decided to make a data store class to handle my data store through out the whole app. I am sure that the functions are being called at appropriate times thanks to the toast message. The main issue is that the pin will always hold the value "tutorial" despite finishing the pin setting phase and seeing a toast that the pin has been updated.
Current Problem Solving:
- It seems that the context being passed isn't the issue as it appears to be the same every time it is launched.
LaunchActivity.kt
class LaunchActivity : AppCompatActivity() {
private val dataModel by viewModels<LaunchVModel>()
private var pin: String? = null
override fun onCreate(savedInstanceState: Bundle?) {
installSplashScreen().apply {
setKeepOnScreenCondition {
!dataModel.isReady.value
}
setOnExitAnimationListener {
// code removed for brevity
}
}
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
if(pin == null) { // no pin option set, start w/ tutorial
replaceFragment(TutorialFragment())
}
else if(pin == "tutorial") { // user chose not to have a pin
switchActivity()
}
else { // user has a pin
replaceFragment(PasscodeFragment())
}
dataModel.pin.observe(this) { // update the pin
pin = dataModel.returnPin()
Toast.makeText(this, "Pin val in View Model...$pin", Toast.LENGTH_SHORT).show()
}
}
}
Basic Data
class BasicData (context: Context) {
private val Context.dataStore : DataStore<Preferences> by preferencesDataStore(name = "LaunchSettings")
private val dataStore = context.dataStore
suspend fun set(key : String, given : String) {
val dataStoreKey = stringPreferencesKey(key)
dataStore.edit{ basics ->
basics[dataStoreKey] = given
}
}
suspend fun retrieve(key: String) : String? {
val dataStoreKey = stringPreferencesKey(key)
val preferences = dataStore.data.first()
return preferences[dataStoreKey]
}
}
ViewModel
class LaunchVModel(application: Application): AndroidViewModel(application) {
// needed for the pause on splash (launch) animation
private val _isReady = MutableStateFlow(false)
val isReady = _isReady.asStateFlow()
private var dataStore = BasicData(application)
var pin = MutableLiveData<String>()
var email = MutableLiveData<String>()
var skip = MutableLiveData<String>()
// immediately execute the splash delay
init {
viewModelScope.launch {
var temp = dataStore.retrieve("pin")
if(temp != null) {
pin.value = temp!!
_isReady.value = true
}
else {
pin.value = "tutorial"
_isReady.value = true
}
}
}
fun returnPin() : String? {
return pin.value.toString()
}
fun data(item: String) {
viewModelScope.launch {
dataStore.set("pin", item)
pin.value = item
}
}
}