'Best practice for storing generic preferences in Realm / Swift
I'm wondering what the best practice is for building a general user preferences mechanism that is backed by RealmSwift.
Ideally the solution will be key/value based and easily extended. My initial thinking on a basic implementation:
protocol DefaultsProvider {
func get(_ key: AvailableDefaults) -> Any?
func get(_ key: String) -> Any?
}
enum AvailableDefaults: String {
case userColorPreference
case otherDefaultThing
}
struct DefaultsManager: DefaultsProvider {
private var defaults: Dictionary<AvailableDefaults, Any> = [:]
func get(_ key: AvailableDefaults) -> Any? { defaults[key] }
func get(_ key: String) -> Any? {
guard let key = AvailableDefaults(rawValue: key) else { return nil }
return defaults[key]
}
}
As an API this is workable and ultimately extensible. For instance, I can easily store, say, an array of enumerated values ([.blue, .green]) as a preference. But it has a couple shortcomings:
- It requires casting results to/from
Any, e.g., to get back that array of enumerations I'd do:defaults.get(.userColorPreference) as! [Colors]). I'm not loving that. - It gets nastier when we look at how to persist this in Realm, since
Anyis not a persistable type. I could wrap default in something that is persistable. For instance:
import RealmSwift
class DefaultValue: Object {
let value: CustomStringConvertible
// Convenience
var asColors: [Colors]? { get { ... }}
}
The above would allow me to persist anything that is CustomStringConvertible (and give me the flexibility to add some convenience functions to the class). Obviously, I could also just put a bunch of convenience functions on the DefaultsProvider, such as getUserColorPrefs.
But the further I go down this path, the more I start to wonder if it just makes more sense to store a struct Defaults or maybe a JSON object in Realm, and be done with it, but that's definitely moving away from a generic, highly extensible defaults provider.
Solution 1:[1]
Looks like you want to try Realm-Swift Type Projections - it allow you to cast Realm-persistable types to whatever you need https://www.mongodb.com/developer/how-to/type-projections/
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Pavel Yakimenko |
