Skip to content

Commit bc258e5

Browse files
authored
Merge pull request #1 from swhitty/userdefaults-native
Native UserDefaults types should be decoded via the existing getter
2 parents c5c12bc + 276a153 commit bc258e5

File tree

2 files changed

+156
-1
lines changed

2 files changed

+156
-1
lines changed

Sources/UserDefaults+Codable.swift

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,14 @@ public extension UserDefaults {
4545

4646
func decode<T: Decodable>(_ type: T.Type = T.self, forKey key: String) throws -> T? {
4747
guard let storage = object(forKey: key) else { return nil }
48-
return try KeyValueDecoder.makePlistCompatible().decode(type, from: storage)
48+
switch type {
49+
case is String.Type: return string(forKey: key) as? T
50+
case is Bool.Type: return bool(forKey: key) as? T
51+
case is Int.Type: return integer(forKey: key) as? T
52+
case is Double.Type: return double(forKey: key) as? T
53+
case is Float.Type: return float(forKey: key) as? T
54+
case is URL.Type: return url(forKey: key) as? T
55+
default: return try KeyValueDecoder.makePlistCompatible().decode(type, from: storage)
56+
}
4957
}
5058
}

Tests/UserDefaults+CodableTests.swift

Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,153 @@ final class UserDefaultsCodableTests: XCTestCase {
176176
)
177177
)
178178
}
179+
180+
func testDecodes_String() {
181+
let defaults = UserDefaults.makeMock()
182+
183+
defaults.set("YES", forKey: "flag")
184+
XCTAssertEqual(
185+
defaults.string(forKey: "flag"),
186+
"YES"
187+
)
188+
XCTAssertEqual(
189+
try defaults.decode(String.self, forKey: "flag"),
190+
"YES"
191+
)
192+
193+
#if canImport(Darwin)
194+
defaults.set(1, forKey: "flag")
195+
XCTAssertEqual(
196+
defaults.string(forKey: "flag"),
197+
"1"
198+
)
199+
XCTAssertEqual(
200+
try defaults.decode(String.self, forKey: "flag"),
201+
"1"
202+
)
203+
#endif
204+
}
205+
206+
func testDecodes_Bool() {
207+
let defaults = UserDefaults.makeMock()
208+
209+
defaults.set("YES", forKey: "flag")
210+
XCTAssertTrue(defaults.bool(forKey: "flag"))
211+
XCTAssertEqual(
212+
try defaults.decode(Bool.self, forKey: "flag"),
213+
true
214+
)
215+
216+
defaults.set("NO", forKey: "flag")
217+
XCTAssertFalse(defaults.bool(forKey: "flag"))
218+
XCTAssertEqual(
219+
try defaults.decode(Bool.self, forKey: "flag"),
220+
false
221+
)
222+
223+
defaults.set("other", forKey: "flag")
224+
XCTAssertFalse(defaults.bool(forKey: "flag"))
225+
XCTAssertEqual(
226+
try defaults.decode(Bool.self, forKey: "flag"),
227+
false
228+
)
229+
}
230+
231+
func testDecodes_Integer() {
232+
let defaults = UserDefaults.makeMock()
233+
234+
defaults.set(1, forKey: "flag")
235+
XCTAssertEqual(
236+
defaults.integer(forKey: "flag"),
237+
1
238+
)
239+
XCTAssertEqual(
240+
try defaults.decode(Int.self, forKey: "flag"),
241+
1
242+
)
243+
244+
defaults.set("2", forKey: "flag")
245+
XCTAssertEqual(
246+
defaults.integer(forKey: "flag"),
247+
2
248+
)
249+
XCTAssertEqual(
250+
try defaults.decode(Int.self, forKey: "flag"),
251+
2
252+
)
253+
}
254+
255+
func testDecodes_Double() {
256+
let defaults = UserDefaults.makeMock()
257+
258+
defaults.set(Double(1.5), forKey: "flag")
259+
XCTAssertEqual(
260+
defaults.double(forKey: "flag"),
261+
1.5
262+
)
263+
XCTAssertEqual(
264+
try defaults.decode(Double.self, forKey: "flag"),
265+
1.5
266+
)
267+
268+
defaults.set("2.5", forKey: "flag")
269+
XCTAssertEqual(
270+
defaults.double(forKey: "flag"),
271+
2.5
272+
)
273+
XCTAssertEqual(
274+
try defaults.decode(Double.self, forKey: "flag"),
275+
2.5
276+
)
277+
}
278+
279+
func testDecodes_Float() {
280+
let defaults = UserDefaults.makeMock()
281+
282+
defaults.set(Float(1.5), forKey: "flag")
283+
XCTAssertEqual(
284+
defaults.float(forKey: "flag"),
285+
1.5
286+
)
287+
XCTAssertEqual(
288+
try defaults.decode(Float.self, forKey: "flag"),
289+
1.5
290+
)
291+
292+
defaults.set("2.5", forKey: "flag")
293+
XCTAssertEqual(
294+
defaults.float(forKey: "flag"),
295+
2.5
296+
)
297+
XCTAssertEqual(
298+
try defaults.decode(Float.self, forKey: "flag"),
299+
2.5
300+
)
301+
}
302+
303+
func testDecodes_URL() {
304+
let defaults = UserDefaults.makeMock()
305+
306+
defaults.set(URL(fileURLWithPath: "/fish"), forKey: "flag")
307+
XCTAssertEqual(
308+
defaults.url(forKey: "flag"),
309+
URL(fileURLWithPath: "/fish")
310+
)
311+
XCTAssertEqual(
312+
try defaults.decode(URL.self, forKey: "flag"),
313+
URL(fileURLWithPath: "/fish")
314+
)
315+
316+
defaults.set("/chips", forKey: "flag")
317+
XCTAssertEqual(
318+
defaults.url(forKey: "flag"),
319+
URL(fileURLWithPath: "/chips")
320+
)
321+
XCTAssertEqual(
322+
try defaults.decode(URL.self, forKey: "flag"),
323+
URL(fileURLWithPath: "/chips")
324+
)
325+
}
179326
}
180327

181328
private extension UserDefaults {

0 commit comments

Comments
 (0)