Skip to content

Commit daf272a

Browse files
committed
Add boolValue(forKey:), doubleValue(forKey:), and intValue(forKey:)
1 parent 29ebf37 commit daf272a

File tree

3 files changed

+169
-2
lines changed

3 files changed

+169
-2
lines changed

Sources/JSON/Dictionary+JSON.swift

+75
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
import Foundation
2+
3+
public extension [String: Any] {
4+
func boolValue(forKey key: String) -> Bool? {
5+
if let v = self[key] as? Bool {
6+
return v
7+
} else if let v = self[key] as? NSNumber, v.isBool {
8+
return v.boolValue
9+
} else {
10+
return nil
11+
}
12+
}
13+
14+
func doubleValue(forKey key: String) -> Double? {
15+
if let v = self[key] as? Double {
16+
return v
17+
} else if let v = self[key] as? NSNumber, !v.isBool {
18+
return v.doubleValue
19+
} else {
20+
return nil
21+
}
22+
}
23+
24+
func intValue(forKey key: String) -> Int? {
25+
if let v = self[key] as? Int {
26+
return v
27+
} else if let v = self[key] as? Double {
28+
return Int(v)
29+
} else if let v = self[key] as? NSNumber, !v.isBool {
30+
return v.intValue
31+
} else {
32+
return nil
33+
}
34+
}
35+
}
36+
37+
public extension [String: Any]? {
38+
func boolValue(forKey key: String) -> Bool? {
39+
if let v = self?[key] as? Bool {
40+
return v
41+
} else if let v = self?[key] as? NSNumber, v.isBool {
42+
return v.boolValue
43+
} else {
44+
return nil
45+
}
46+
}
47+
48+
func doubleValue(forKey key: String) -> Double? {
49+
if let v = self?[key] as? Double {
50+
return v
51+
} else if let v = self?[key] as? NSNumber, !v.isBool {
52+
return v.doubleValue
53+
} else {
54+
return nil
55+
}
56+
}
57+
58+
func intValue(forKey key: String) -> Int? {
59+
if let v = self?[key] as? Int {
60+
return v
61+
} else if let v = self?[key] as? Double {
62+
return Int(v)
63+
} else if let v = self?[key] as? NSNumber, !v.isBool {
64+
return v.intValue
65+
} else {
66+
return nil
67+
}
68+
}
69+
}
70+
71+
private extension NSNumber {
72+
var isBool: Bool {
73+
CFBooleanGetTypeID() == CFGetTypeID(self)
74+
}
75+
}
+92
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
import JSON
2+
import XCTest
3+
4+
final class DictionaryJSONTests: XCTestCase {
5+
func testValueForKey() throws {
6+
let original: [String: Any] = [
7+
"one": 1,
8+
"oneoh": 1.0,
9+
"onenum": NSNumber(value: 1),
10+
"pie": 3.14,
11+
"pienum": NSNumber(value: 3.14),
12+
"tru": true,
13+
"trunum": NSNumber(value: true),
14+
"fals": false,
15+
"falsnum": NSNumber(value: false),
16+
]
17+
18+
let json = JSON(original as [String: Any?])
19+
20+
let dict = try XCTUnwrap(json.dictionaryValue)
21+
22+
XCTAssertEqual(1, dict.intValue(forKey: "one"))
23+
XCTAssertEqual(1, dict.intValue(forKey: "oneoh"))
24+
XCTAssertEqual(1, dict.intValue(forKey: "onenum"))
25+
26+
XCTAssertEqual(3.14, dict.doubleValue(forKey: "pie"))
27+
XCTAssertEqual(3.14, dict.doubleValue(forKey: "pienum"))
28+
29+
XCTAssertEqual(3, dict.intValue(forKey: "pie"))
30+
XCTAssertEqual(3, dict.intValue(forKey: "pienum"))
31+
32+
XCTAssertEqual(true, dict.boolValue(forKey: "tru"))
33+
XCTAssertEqual(true, dict.boolValue(forKey: "trunum"))
34+
35+
XCTAssertEqual(false, dict.boolValue(forKey: "fals"))
36+
XCTAssertEqual(false, dict.boolValue(forKey: "falsnum"))
37+
38+
XCTAssertNil(dict.boolValue(forKey: "one"))
39+
XCTAssertNil(dict.boolValue(forKey: "oneoh"))
40+
XCTAssertNil(dict.boolValue(forKey: "onenum"))
41+
42+
XCTAssertNil(dict.doubleValue(forKey: "tru"))
43+
XCTAssertNil(dict.doubleValue(forKey: "fals"))
44+
45+
XCTAssertNil(dict.intValue(forKey: "tru"))
46+
XCTAssertNil(dict.intValue(forKey: "fals"))
47+
}
48+
49+
func testValueForKeyOfOptionalDictionary() throws {
50+
let original: [String: Any] = [
51+
"one": 1,
52+
"oneoh": 1.0,
53+
"onenum": NSNumber(value: 1),
54+
"pie": 3.14,
55+
"pienum": NSNumber(value: 3.14),
56+
"tru": true,
57+
"trunum": NSNumber(value: true),
58+
"fals": false,
59+
"falsnum": NSNumber(value: false),
60+
]
61+
62+
let json = JSON(original as [String: Any?])
63+
64+
let dict = json.dictionaryValue
65+
66+
XCTAssertEqual(1, dict.intValue(forKey: "one"))
67+
XCTAssertEqual(1, dict.intValue(forKey: "oneoh"))
68+
XCTAssertEqual(1, dict.intValue(forKey: "onenum"))
69+
70+
XCTAssertEqual(3.14, dict.doubleValue(forKey: "pie"))
71+
XCTAssertEqual(3.14, dict.doubleValue(forKey: "pienum"))
72+
73+
XCTAssertEqual(3, dict.intValue(forKey: "pie"))
74+
XCTAssertEqual(3, dict.intValue(forKey: "pienum"))
75+
76+
XCTAssertEqual(true, dict.boolValue(forKey: "tru"))
77+
XCTAssertEqual(true, dict.boolValue(forKey: "trunum"))
78+
79+
XCTAssertEqual(false, dict.boolValue(forKey: "fals"))
80+
XCTAssertEqual(false, dict.boolValue(forKey: "falsnum"))
81+
82+
XCTAssertNil(dict.boolValue(forKey: "one"))
83+
XCTAssertNil(dict.boolValue(forKey: "oneoh"))
84+
XCTAssertNil(dict.boolValue(forKey: "onenum"))
85+
86+
XCTAssertNil(dict.doubleValue(forKey: "tru"))
87+
XCTAssertNil(dict.doubleValue(forKey: "fals"))
88+
89+
XCTAssertNil(dict.intValue(forKey: "tru"))
90+
XCTAssertNil(dict.intValue(forKey: "fals"))
91+
}
92+
}

Tests/JSONTests/JSONTests.swift

+2-2
Original file line numberDiff line numberDiff line change
@@ -84,9 +84,9 @@ final class JSONTests: XCTestCase {
8484
"dict": [
8585
"key": "value",
8686
"double": 3.14,
87-
] as [String: Any]
87+
] as [String: Any],
8888
]
89-
89+
9090
let one: Int? = object["one"]
9191
XCTAssertEqual(1, one)
9292
let notOne: String? = object["one"]

0 commit comments

Comments
 (0)