Skip to content

Commit d5caace

Browse files
committed
Support storing codable object in UserDefaults
1 parent d16d1c7 commit d5caace

1 file changed

Lines changed: 44 additions & 0 deletions

File tree

Tool/Sources/Preferences/UserDefaults.swift

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,32 @@ extension Array: RawRepresentable where Element: Codable {
6363
}
6464
}
6565

66+
public struct UserDefaultsStorageBox<Element: Codable>: RawRepresentable {
67+
public let value: Element
68+
69+
public init(_ value: Element) {
70+
self.value = value
71+
}
72+
73+
public init?(rawValue: String) {
74+
guard let data = rawValue.data(using: .utf8),
75+
let result = try? JSONDecoder().decode(Element.self, from: data)
76+
else {
77+
return nil
78+
}
79+
value = result
80+
}
81+
82+
public var rawValue: String {
83+
guard let data = try? JSONEncoder().encode(value),
84+
let result = String(data: data, encoding: .utf8)
85+
else {
86+
return ""
87+
}
88+
return result
89+
}
90+
}
91+
6692
public extension UserDefaultsType {
6793
// MARK: Normal Types
6894

@@ -121,6 +147,16 @@ public extension UserDefaultsType {
121147
}
122148
return K.Value(rawValue: rawValue) ?? key.defaultValue
123149
}
150+
151+
func value<K: UserDefaultPreferenceKey, V>(
152+
for keyPath: KeyPath<UserDefaultPreferenceKeys, K>
153+
) -> V where K.Value == UserDefaultsStorageBox<V> {
154+
let key = UserDefaultPreferenceKeys()[keyPath: keyPath]
155+
guard let rawValue = value(forKey: key.key) as? String else {
156+
return key.defaultValue.value
157+
}
158+
return (K.Value(rawValue: rawValue) ?? key.defaultValue).value
159+
}
124160

125161
func set<K: UserDefaultPreferenceKey>(
126162
_ value: K.Value,
@@ -137,6 +173,14 @@ public extension UserDefaultsType {
137173
let key = UserDefaultPreferenceKeys()[keyPath: keyPath]
138174
set(value.rawValue, forKey: key.key)
139175
}
176+
177+
func set<K: UserDefaultPreferenceKey, V: Codable>(
178+
_ value: V,
179+
for keyPath: KeyPath<UserDefaultPreferenceKeys, K>
180+
) where K.Value == UserDefaultsStorageBox<V> {
181+
let key = UserDefaultPreferenceKeys()[keyPath: keyPath]
182+
set(UserDefaultsStorageBox(value).rawValue, forKey: key.key)
183+
}
140184

141185
func setupDefaultValue<K: UserDefaultPreferenceKey>(
142186
for keyPath: KeyPath<UserDefaultPreferenceKeys, K>,

0 commit comments

Comments
 (0)