```var realtimeTypeSupported: Int = 0 get() { ...
# getting-started
c
Copy code
var realtimeTypeSupported: Int = 0
    get() {
        coroutineScope.async {
            field = preference.read(REALTIME_COMMUNICATION_TYPE) ?: 0
            return@async field
        }
        return field
    }
    set(value) {
        coroutineScope.launch {
            preference.write(REALTIME_COMMUNICATION_TYPE, value)
            field = value
        }
    }
    var messageTypeSupported: Int = 0
    get() {
        coroutineScope.async {
            field = preference.read(MESSAGE_TYPE) ?: 0
            return@async field
        }
        return field
    }
    set(value) {
        coroutineScope.launch {
            preference.write(MESSAGE_TYPE, value)
            field = value
        }
    }
how to group them into one definition? if there are more than ten such variables.
g
If you have logic that changes only in one value then you can abstract it. For example, write a class like following
Copy code
class PreferenceAccessor(
    val coroutineScope: CoroutineScope,
    val preference: ...,
    val code: ...,
    var field: Int = 0,
) {
    operator fun getValue(thisRef: Any?, property: KProperty<*>): Int {
        coroutineScope.async {
            field = preference.read(code) ?: 0
            return@async field
        }
        return field
    }
    operator fun setValue(thisRef: Any?, property: KProperty<*>, value: Int) {
        coroutineScope.launch {
            preference.write(code, value)
            field = value
        }
    }
}
that you can use like
Copy code
var realtimeTypeSupported: Int by PreferenceAccessor(coroutineScope, preference, REALTIME_COMMUNICATION_TYPE)
var messageTypeSupported: Int by PreferenceAccessor(coroutineScope, preference, MESSAGE_TYPE)
👍 1
r
Just to add that the
get
code as posted will not work correctly because you're not waiting for the
async
to finish. The first time it's called will always return the initial value (0) and future calls may return either the initial or fetched value depending on how long it's been since the first call.
2
k
Indeed, to add to what Robert says, the posted code looks as if there's some misunderstanding about how it works. The expression
return@async field
is the same as just putting
field
on that line: it causes your lambda to returns the value of the field back to the
async
method, and the
async
method would return that value if you called
await
on it. However, you're not, and the value is ignored. Your
get
does the same thing as if you had used
launch
(and omitted the
return@async
) instead of
async
.
😂 1
💯 1
c
Thanks to all. Preference DataStore has been replaced by SharedPreferences.
Copy code
class PreferenceAccessor(
    val preference: SharedPreferences,
    val key: String,
    var field: Int = 0
) {
    operator fun getValue(thisRef: Any?, property: KProperty<*>): Int {
        return preference.getInt(key, 0)
    }

    operator fun setValue(thisRef: Any?, property: KProperty<*>, value: Int) {
        var editor = preference.edit()
        editor.putInt(key, value)
        editor.commit()
        field = value
    }
}
tests passed with the above code.