Skip to content

Instantly share code, notes, and snippets.

@IanKeen
Last active July 9, 2022 17:31
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save IanKeen/b259f8dec252944fffb569e6f325e486 to your computer and use it in GitHub Desktop.
Save IanKeen/b259f8dec252944fffb569e6f325e486 to your computer and use it in GitHub Desktop.
Simple type safe wrapper around UserDefaults
extension UserDefaultsKey {
static var foo: UserDefaultsKey<SomeType> { .init(name: "foo", default: .init(value: "foo")) }
}
struct SomeType: Codable {
var value: String
}
UserDefaults.standard.get(.foo) // .init(value: "foo")
UserDefaults.standard.set(.foo, .init(value: "bar"))
UserDefaults.standard.get(.foo) // .init(value: "bar")
struct UserDefaultsKey<T: Codable> {
var name: String
var `default`: T
}
extension UserDefaults {
func get<T>(_ key: UserDefaultsKey<T>) -> T {
guard
let data = data(forKey: key.name),
let box = try? JSONDecoder().decode(Box<T>.self, from: data)
else { return key.default }
return box.value
}
func set<T>(_ key: UserDefaultsKey<T>, _ value: T?) {
if let value = value {
let box = Box(value: value)
if let data = try? JSONEncoder().encode(box) {
set(data, forKey: key.name)
} else {
removeObject(forKey: key.name)
}
} else {
removeObject(forKey: key.name)
}
}
}
private struct Box<T: Codable>: Codable {
var value: T
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment