diff --git a/Alexander/JSON.swift b/Alexander/JSON.swift index 38f0429..d66530e 100644 --- a/Alexander/JSON.swift +++ b/Alexander/JSON.swift @@ -25,50 +25,42 @@ public struct JSON { public var object: AnyObject - public subscript(index: Int) -> JSON? { - let array = object as? [AnyObject] - return (array?[index]).map({ JSON(object: $0) }) - } - - public subscript(key: String) -> JSON? { - let dictionary = object as? [String: AnyObject] - return (dictionary?[key]).map({ JSON(object: $0) }) - } - - public var string: String? { - return object as? String + public var array: [JSON]? { + return arrayValue?.map({ JSON(object: $0) }) } public var dictionary: [String: JSON]? { - return (object as? [String: AnyObject])?.mapValues({ JSON(object: $0) }) + return dictionaryValue?.mapValues({ JSON(object: $0) }) } - public var array: [JSON]? { - return (object as? [AnyObject])?.map({ JSON(object: $0) }) + public var arrayValue: [AnyObject]? { + return object as? [AnyObject] } - public var int: Int? { - return object as? Int + public var dictionaryValue: [String: AnyObject]? { + return object as? [String: AnyObject] } - public var double: Double? { - return object as? Double + public subscript(index: Int) -> JSON? { + let array = object as? [AnyObject] + return (array?[index]).map({ JSON(object: $0) }) } - public var bool: Bool? { - return object as? Bool + public subscript(key: String) -> JSON? { + let dictionary = object as? [String: AnyObject] + return (dictionary?[key]).map({ JSON(object: $0) }) } - public var url: NSURL? { - return string.flatMap({ NSURL(string: $0) }) + public var stringValue: String? { + return object as? String } - public var timeInterval: NSTimeInterval? { - return object as? NSTimeInterval + public var intValue: Int? { + return object as? Int } - public var date: NSDate? { - return timeInterval.map({ NSDate(timeIntervalSince1970: $0) }) + public var boolValue: Bool? { + return object as? Bool } @@ -84,6 +76,14 @@ public struct JSON { .map(transform) .flatMap({ $0 }) } + + public func decode(type: T.Type) -> T? { + return (object as? T.RawValue).flatMap(T.init) + } + + public func decodeArray(type: T.Type) -> [T]? { + return (object as? [T.RawValue])?.lazy.map(T.init).flatMap({ $0 }) + } } extension JSON { @@ -112,11 +112,36 @@ extension JSON: CustomDebugStringConvertible { } extension JSON { - public func decode(type: T.Type) -> T? { - return (object as? T.RawValue).flatMap(T.init) + @available(*, deprecated, message = "Use stringValue instead.") + public var string: String? { + return stringValue } - public func decodeArray(type: T.Type) -> [T]? { - return (object as? [T.RawValue])?.lazy.map(T.init).flatMap({ $0 }) + @available(*, deprecated, message = "Use intValue instead.") + public var int: Int? { + return intValue + } + + public var double: Double? { + return object as? Double + } + + @available(*, deprecated, message = "Use boolValue instead.") + public var bool: Bool? { + return boolValue + } + + @available(*, deprecated, message = "Use decode(NSURL) instead.") + public var url: NSURL? { + return decode(NSURL) + } + + public var timeInterval: NSTimeInterval? { + return object as? NSTimeInterval + } + + @available(*, deprecated, message = "Use decode(NSDate) instead.") + public var date: NSDate? { + return decode(NSDate) } } diff --git a/Alexander/JSONCodable.swift b/Alexander/JSONCodable.swift index 7822ae9..5590208 100644 --- a/Alexander/JSONCodable.swift +++ b/Alexander/JSONCodable.swift @@ -23,3 +23,15 @@ public extension Alexander.JSON { return decodeArray(T.decode) } } + +extension NSURL: JSONDecodable { + public static func decode(JSON: Alexander.JSON) -> Self? { + return JSON.stringValue.flatMap(self.init) + } +} + +extension NSDate: JSONDecodable { + public static func decode(JSON: Alexander.JSON) -> Self? { + return (JSON.object as? NSTimeInterval).flatMap({ self.init(timeIntervalSince1970: $0) }) + } +} diff --git a/Tests/AlexanderTests.swift b/Tests/AlexanderTests.swift index d018d47..d6a3f98 100644 --- a/Tests/AlexanderTests.swift +++ b/Tests/AlexanderTests.swift @@ -14,11 +14,11 @@ final class AlexanderTests: XCTestCase { func testArray() { let JSON = Alexander.JSON(object: ["1","2", "a", "B", "D"]) XCTAssertEqual(JSON.array?.count, 5) - XCTAssertEqual(JSON[0]?.string, "1") - XCTAssertEqual(JSON[1]?.string, "2") - XCTAssertEqual(JSON[2]?.string, "a") - XCTAssertEqual(JSON[3]?.string, "B") - XCTAssertEqual(JSON[4]?.string, "D") + XCTAssertEqual(JSON[0]?.stringValue, "1") + XCTAssertEqual(JSON[1]?.stringValue, "2") + XCTAssertEqual(JSON[2]?.stringValue, "a") + XCTAssertEqual(JSON[3]?.stringValue, "B") + XCTAssertEqual(JSON[4]?.stringValue, "D") } func testDictionary() { @@ -37,9 +37,9 @@ final class AlexanderTests: XCTestCase { let JSON = Alexander.JSON(object: dictionary) XCTAssertEqual(JSON["double"]?.double, 9823.212) - XCTAssertEqual(JSON["int"]?.int, 42) - XCTAssertEqual(JSON["string"]?.string, "Caleb") - XCTAssertEqual(JSON["bool"]?.bool, true) + XCTAssertEqual(JSON["int"]?.intValue, 42) + XCTAssertEqual(JSON["string"]?.stringValue, "Caleb") + XCTAssertEqual(JSON["bool"]?.boolValue, true) XCTAssertEqual(JSON["array"]?.array?.count, 2) XCTAssertEqual(JSON["array"]?[0]?.double, 1234) @@ -47,7 +47,7 @@ final class AlexanderTests: XCTestCase { XCTAssertEqual(JSON["object"]?.dictionary?.count, 2) XCTAssertEqual(JSON["object"]?["double"]?.double, 877.2323) - XCTAssertEqual(JSON["object"]?["string"]?.string, "Jon") + XCTAssertEqual(JSON["object"]?["string"]?.stringValue, "Jon") XCTAssertNil(JSON["null"]) } @@ -89,7 +89,7 @@ final class AlexanderTests: XCTestCase { var name: String static func decode(JSON: Alexander.JSON) -> User? { - guard let ID = JSON["id"]?.string, let name = JSON["name"]?.string else { + guard let ID = JSON["id"]?.stringValue, let name = JSON["name"]?.stringValue else { return nil } return User(ID: ID, name: name) @@ -114,7 +114,7 @@ final class AlexanderTests: XCTestCase { var name: String static func decode(JSON: Alexander.JSON) -> User? { - guard let ID = JSON["id"]?.string, let name = JSON["name"]?.string else { + guard let ID = JSON["id"]?.stringValue, let name = JSON["name"]?.stringValue else { return nil } return User(ID: ID, name: name) @@ -148,14 +148,18 @@ final class AlexanderTests: XCTestCase { func testURLHelpers() { let JSON = Alexander.JSON(object: "https://www.hodinkee.com") - let URL = JSON.url - XCTAssertNotNil(URL) + + guard let URL = JSON.decode(NSURL) else { + XCTFail() + return + } + XCTAssertEqual(URL, NSURL(string: "https://www.hodinkee.com")) } func testDateHelpers() { let JSON = Alexander.JSON(object: 978307200) XCTAssertEqual(JSON.timeInterval, NSDate(timeIntervalSinceReferenceDate: 0).timeIntervalSince1970) - XCTAssertEqual(JSON.date, NSDate(timeIntervalSinceReferenceDate: 0)) + XCTAssertEqual(JSON.decode(NSDate), NSDate(timeIntervalSinceReferenceDate: 0)) } }