So I've written a class for storing user/device specific settings, but I've written the Kotlin pretty much like I would in Java:
import android.content.Context
import android.content.SharedPreferences
import java.util.*
class UserSettings {
private lateinit var _prefs :SharedPreferences
fun UserSettings(ctx : Context) {
_prefs = ctx.getSharedPreferences("UserSettings", Context.MODE_PRIVATE)
}
private val KEY_DEVICEID = "deviceId"
var deviceId :String
get() {
var value = _prefs.getString(KEY_DEVICEID, null)
if (null == value) {
value = UUID.randomUUID().toString()
this.deviceId = value
}
return value
}
set(it) {
_prefs.edit()
.putString(KEY_DEVICEID, it)
.apply()
}
}
This feels really verbose. I've considered writing a helper library to simply store all values from a class in SharedPreferences
via reflection, but I'm not sure if that's overkill. The above code obviously only has one value at the moment, but I'll be adding a couple more that will look very similar to the above.
1 Answer 1
Welcome to Kotlin! Consider this.
// Define constructor this way
class UserSettings(context: Context) {
// Prefixes for fields are rather uncommon in the Kotlin world.
// You could remove the type declaration here - Kotlin will infer it for you
private val prefs: SharedPreferences = context
.getSharedPreferences("UserSettings", Context.MODE_PRIVATE)
var deviceId: String
get() = prefs.getString(KEY_DEVICE_ID, null) ?: UUID.randomUUID().toString().also {
// `also` block will execute only in case we return a new UUID.
deviceId = it
}
set(it) {
prefs
.edit()
.putString(KEY_DEVICE_ID, it)
.apply()
}
companion object {
// Depends on a taste / convention your team uses.
// I like keeping my key constants within the companion object.
private const val KEY_DEVICE_ID = "deviceId"
}
}
For simplifying it even more, consider using Android KTX - it has some handy SharedPreferences
extensions, described here: https://developer.android.com/kotlin/ktx