Saturday, 20 August 2022

Preferences are neither read nor written

I am working on app settings. I am doing this in Jetpack Compose. However, when the switch button is clicked and changed to true or false, this is printed out during debug, however, the settings don't appear to change nor be saved. No way to confirm this.

Not sure of LaunchEffect{} shall be used.

AppSettings:

import kotlinx.serialization.Serializable

@Serializable
data class AppSettings(
    val enableLocation: Boolean = false
)

AppSettingsSerializer:

object AppSettingsSerializer : Serializer<AppSettings> {
    override val defaultValue: AppSettings
        get() = AppSettings()

   
    override suspend fun readFrom(input: InputStream): AppSettings {
        return try {
            Json.decodeFromString(
                deserializer = AppSettings.serializer(),
                string = input.readBytes().decodeToString())
        } catch (e: SerializationException){
            e.printStackTrace()
            defaultValue
        }
    }

    override suspend fun writeTo(t: AppSettings, output: OutputStream) {
        output.write(
            Json.encodeToString(
                serializer = AppSettings.serializer(),
                value = t)
                .encodeToByteArray()
        )
    }
}

SettingsViewModel:

@HiltViewModel
class SettingsViewModel @Inject constructor(
    val preferencesRepository: PreferencesRepository
) : ViewModel() {
    var preferences by mutableStateOf(AppSettings())
        private set

    init {
        preferencesRepository.data
            .onEach { preferences = it }
            .launchIn(viewModelScope)
    }

    inline fun updatePreferences(crossinline body: (AppSettings) -> AppSettings) {
        viewModelScope.launch {
            val data = body(preferences)
            preferencesRepository.updateSettings(data)
        }
    }
}

PreferenceRepository:

class PreferencesRepository(context: Context){
    private val Context.dataStore by dataStore(
        fileName = "app-settings.json",
        serializer = AppSettingsSerializer
    )

    private val appDataStore = context.dataStore
    val data = appDataStore.data

    suspend fun updateSettings(settings: AppSettings) {
        appDataStore.updateData { settings }
    }
}

Inside settings screen:

item {
    SwitchPreference(
        title = stringResource(R.string.location),
        subtitle = AnnotatedString(stringResource(R.string.location_desc)),
        checked = settings.enableLocation,
        onCheckedChange = {location ->
            viewModel.updatePreferences { it.copy(enableLocation = location) }
        }
    )
}


from Preferences are neither read nor written

No comments:

Post a Comment