Created
May 14, 2021 18:20
-
-
Save noahsark769/9b161e8aa4fbd003e9dc2986babc01ed to your computer and use it in GitHub Desktop.
User Defaults Property Wrappers
This file contains hidden or 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
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