Skip to content

Instantly share code, notes, and snippets.

@Nirajpaul2
Last active April 15, 2022 04:57
Show Gist options
  • Save Nirajpaul2/5bfd1117e6f7eb33d5b77c1f1decf6e1 to your computer and use it in GitHub Desktop.
Save Nirajpaul2/5bfd1117e6f7eb33d5b77c1f1decf6e1 to your computer and use it in GitHub Desktop.
CustomObjectUserDefaultWrapper
import Foundation
import Combine
@propertyWrapper
struct CustomObjectUserDefaultWrapper<Value: Codable> {
let key: String
let defaultValue: Value
var container: UserDefaults = .standard
private let publisher = PassthroughSubject<Value, Never>()
var wrappedValue: Value {
get {
// Read value from UserDefaults
guard let data = container.object(forKey: key) as? Data else {
// Return defaultValue when no data in UserDefaults
return defaultValue
}
// Convert data to the desire data type
let cdata = try? JSONDecoder().decode(Value.self, from: data)
return cdata ?? defaultValue
}
set {
if let optional = newValue as? AnyOptional, optional.isNil {
container.removeObject(forKey: key)
} else {
// Convert newValue to data
let data = try? JSONEncoder().encode(newValue)
// Set value to UserDefaults
container.set(data, forKey: key)
}
}
}
var projectedValue: AnyPublisher<Value, Never> {
return publisher.eraseToAnyPublisher()
}
}
extension CustomObjectUserDefaultWrapper where Value: ExpressibleByNilLiteral {
/// Creates a new User Defaults property wrapper for the given key.
/// - Parameters:
/// - key: The key to use with the user defaults store.
init(key: String, _ container: UserDefaults = .standard) {
self.init(key: key, defaultValue: nil, container: container)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment