Last active
December 14, 2021 09:41
-
-
Save milis92/f424f52080ba098d9a031ff013325a5a to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.ivan.store | |
import android.content.SharedPreferences | |
import androidx.core.content.edit | |
interface KeyValueStore { | |
fun write(key: String, value: Any?) | |
fun <T> read(key: String): T? | |
fun remove(key: String) | |
fun prune() | |
fun contains(key: String): Boolean | |
fun all(): Map<String, Any?> | |
fun registerObserver(keyValueStoreListener: KeyValueStoreListener) | |
fun unregisterObserver(keyValueStoreListener: KeyValueStoreListener) | |
} | |
fun KeyValueStore.getKeysWithPrefix(prefix: String) = | |
all().filter { it.key.startsWith(prefix) }.keys | |
fun KeyValueStore.removeWithPrefix(prefix: String) { | |
runCatching { | |
getKeysWithPrefix(prefix).forEach { remove(it) } | |
} | |
} | |
fun KeyValueStore.doOnce(key: String, action: () -> Unit) { | |
if (read<Any>(key) == null) { | |
write(key, true) | |
action() | |
} | |
} | |
class KeyValueStoreListener( | |
private val valuesFilter: (key: String) -> Boolean, | |
private val onValueChanged: (key: String) -> Unit | |
) { | |
companion object { | |
fun forKeys(keys: List<String>, onValueChanged: (key: String) -> Unit) = | |
KeyValueStoreListener( | |
valuesFilter = { keys.contains(it) }, | |
onValueChanged = onValueChanged | |
) | |
} | |
internal val preferenceListener by lazy { | |
SharedPreferences.OnSharedPreferenceChangeListener { _, key -> | |
if (valuesFilter(key)) onValueChanged(key) | |
} | |
} | |
} | |
internal class SharedPreferencesKeyValueStore( | |
private val sharedPreferences: SharedPreferences | |
) : KeyValueStore { | |
override fun write(key: String, value: Any?) = | |
sharedPreferences.edit { | |
when (value) { | |
is String -> putString(key, value) | |
is Boolean -> putBoolean(key, value) | |
is Int -> putInt(key, value) | |
is Float -> putFloat(key, value) | |
is Long -> putLong(key, value) | |
is Set<*> -> putStringSet(key, value.map { it.toString() }.toSet()) | |
} | |
} | |
fun write(key: String, value: Set<String?>) { | |
sharedPreferences.edit { | |
putStringSet(key, value) | |
} | |
} | |
@Suppress("UNCHECKED_CAST") | |
override fun <T> read(key: String): T? { | |
return kotlin.runCatching { sharedPreferences.all[key] as? T? }.getOrNull() | |
} | |
override fun remove(key: String) { | |
sharedPreferences.edit { | |
remove(key) | |
} | |
} | |
override fun prune() { | |
sharedPreferences.edit { | |
clear() | |
} | |
} | |
override fun contains(key: String): Boolean { | |
return sharedPreferences.contains(key) | |
} | |
override fun all(): Map<String, Any?> { | |
return sharedPreferences.all ?: emptyMap() | |
} | |
override fun registerObserver(keyValueStoreListener: KeyValueStoreListener) { | |
sharedPreferences.registerOnSharedPreferenceChangeListener( | |
keyValueStoreListener.preferenceListener | |
) | |
} | |
override fun unregisterObserver(keyValueStoreListener: KeyValueStoreListener) { | |
sharedPreferences.unregisterOnSharedPreferenceChangeListener( | |
keyValueStoreListener.preferenceListener | |
) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment