Skip to content

Instantly share code, notes, and snippets.

@noahsark769
Created May 14, 2021 18:20
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 noahsark769/9b161e8aa4fbd003e9dc2986babc01ed to your computer and use it in GitHub Desktop.
Save noahsark769/9b161e8aa4fbd003e9dc2986babc01ed to your computer and use it in GitHub Desktop.
User Defaults Property Wrappers
import Foundation
@propertyWrapper
struct SimpleUserDefault<T> {
let userDefaults: UserDefaults
let key: String
let defaultValue: T
init(
userDefaults: UserDefaults = UserDefaults.standard,
key: String,
defaultValue: T
) {
self.userDefaults = userDefaults
self.key = key
self.defaultValue = defaultValue
}
var wrappedValue: T {
get {
guard let data = userDefaults.object(forKey: key) as? T else { return self.defaultValue }
return data
}
set {
userDefaults.set(newValue, forKey: key)
}
}
}
@propertyWrapper
struct OptionalUserDefault<T> {
let userDefaults: UserDefaults
let key: String
init(
userDefaults: UserDefaults = UserDefaults.standard,
key: String
) {
self.userDefaults = userDefaults
self.key = key
}
var wrappedValue: T? {
get {
guard let data = userDefaults.object(forKey: key) as? T else { return nil }
return data
}
set {
if let newValue = newValue {
userDefaults.set(newValue, forKey: key)
} else {
userDefaults.removeObject(forKey: key)
}
}
}
}
@propertyWrapper
struct ComplexUserDefault<T: Codable> {
let userDefaults: UserDefaults
let key: String
init(
userDefaults: UserDefaults = UserDefaults.standard,
key: String
) {
self.userDefaults = userDefaults
self.key = key
}
var wrappedValue: T? {
get {
guard let data = userDefaults.data(forKey: key) else { return nil }
let object = try? JSONDecoder().decode(T.self, from: data)
return object
}
set {
guard let object = newValue else { return }
let data = try? JSONEncoder().encode(object)
userDefaults.set(data, forKey: key)
}
}
}
@propertyWrapper
struct ArchiverUserDefault<T: NSObject & NSCoding> {
let userDefaults: UserDefaults
let key: String
let defaultValue: T
init(
userDefaults: UserDefaults = UserDefaults.standard,
key: String,
defaultValue: T
) {
self.userDefaults = userDefaults
self.key = key
self.defaultValue = defaultValue
}
var wrappedValue: T {
get {
guard let data = userDefaults.data(forKey: key) else { return defaultValue }
do {
guard let object = try NSKeyedUnarchiver.unarchivedObject(ofClass: T.self, from: data) else {
return defaultValue
}
return object
} catch {
NonFatalManager.shared.log(
"error_unarchiving_user_defaults",
"Unable to unarchive data for user defaults (\(key)). Error: \(error)"
)
return defaultValue
}
}
nonmutating set {
do {
let data = try NSKeyedArchiver.archivedData(withRootObject: newValue, requiringSecureCoding: false)
userDefaults.set(data, forKey: key)
} catch {
NonFatalManager.shared.log(
"error_archiving_user_defaults",
"Unable to archive data for user defaults (\(key)). Error: \(error)"
)
return
}
}
}
var projectedValue: Binding<T> {
return Binding(get: {
return self.wrappedValue
}, set: {
self.wrappedValue = $0
})
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment