Last active
          November 10, 2016 00:14 
        
      - 
      
 - 
        
Save jarsen/0f0919d3f43b2a2268e6 to your computer and use it in GitHub Desktop.  
Revisions
- 
        
jarsen revised this gist
Dec 16, 2015 . No changes.There are no files selected for viewing
 - 
        
jarsen revised this gist
Dec 16, 2015 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -51,7 +51,7 @@ public protocol JSONValueType { extension JSONValueType { public static func JSONValue(object: Any) throws -> ValueType { guard let objectValue = object as? ValueType else { throw JSONError.TypeMismatch(expected: ValueType.self, actual: object.dynamicType) } return objectValue }  - 
        
jarsen revised this gist
Dec 16, 2015 . 1 changed file with 4 additions and 4 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -136,6 +136,10 @@ extension Dictionary where Key: JSONKeyType { throw JSONError.KeyNotFound(key: key) } if let _ = accumulator as? NSNull { throw JSONError.NullValue(key: key) } return accumulator } @@ -145,10 +149,6 @@ extension Dictionary where Key: JSONKeyType { throw JSONError.TypeMismatchWithKey(key: key, expected: A.self, actual: any.dynamicType) } return result }  - 
        
jarsen revised this gist
Oct 16, 2015 . 1 changed file with 39 additions and 5 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -43,14 +43,14 @@ extension String: JSONKeyType { // public protocol JSONValueType { typealias ValueType = Self static func JSONValue(object: Any) throws -> ValueType } extension JSONValueType { public static func JSONValue(object: Any) throws -> ValueType { guard let objectValue = object as? ValueType else { throw JSONError.TypeMismatch(expected: JSONValue.self, actual: object.dynamicType) } return objectValue @@ -95,6 +95,27 @@ extension NSURL: JSONValueType { } } // // MARK: - JSONObjectConvertible // public protocol JSONObjectConvertible : JSONValueType { typealias ConvertibleType = Self init(json: JSONObject) throws } extension JSONObjectConvertible { public static func JSONValue(object: Any) throws -> ConvertibleType { guard let json = object as? JSONObject else { throw JSONError.TypeMismatch(expected: JSONObject.self, actual: object.dynamicType) } guard let value = try self.init(json: json) as? ConvertibleType else { throw JSONError.TypeMismatch(expected: ConvertibleType.self, actual: object.dynamicType) } return value } } // // MARK: - JSONObject // @@ -156,7 +177,17 @@ extension Dictionary where Key: JSONKeyType { // MARK: - Tests // struct User : JSONObjectConvertible { let name: String let email: String init(json: JSONObject) throws { name = try json.JSONValueForKey("name") email = try json.JSONValueForKey("email") } } var json: JSONObject = ["url": "http://apple.com", "foo": (2 as NSNumber), "str": "Hello, World!", "array": [1,2,3,4,7], "object": ["foo": (3 as NSNumber), "str": "Hello, World!"], "bool": (true as NSNumber), "urls": ["http://apple.com", "http://google.com"], "user": ["name": "Jason", "email": "[email protected]"], "users": [["name": "Jason", "email": "[email protected]"], ["name": "Bob", "email": "[email protected]"]]] do { var str: String = try json.JSONValueForKey("str") // var foo1: String = try json.JSONValueForKey("foo") @@ -169,6 +200,9 @@ do { let innerfoo2: Int = try json.JSONValueForKey("object.foo") let bool: Bool = try json.JSONValueForKey("bool") let url: NSURL = try json.JSONValueForKey("url") let urls: [NSURL] = try json.JSONValueForKey("urls") let user: User = try json.JSONValueForKey("user") let users: [User] = try json.JSONValueForKey("users") } catch { print("\(error)")  - 
        
jarsen revised this gist
Oct 16, 2015 . 1 changed file with 2 additions and 2 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -70,10 +70,10 @@ extension Bool: JSONValueType {} extension Array where Element: JSONValueType { public static func JSONValue(object: Any) throws -> [Element] { guard let anyArray = object as? [AnyObject] else { throw JSONError.TypeMismatch(expected: self, actual: object.dynamicType) } return try anyArray.map { try Element.JSONValue($0) as! Element } } }  - 
        
jarsen revised this gist
Oct 15, 2015 . 1 changed file with 5 additions and 5 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -136,7 +136,7 @@ extension Dictionary where Key: JSONKeyType { return try Array<A>.JSONValue(any) } public func JSONValueForKey<A: JSONValueType>(key: Key) throws -> A? { do { return try self.JSONValueForKey(key) as A } @@ -161,11 +161,11 @@ do { var str: String = try json.JSONValueForKey("str") // var foo1: String = try json.JSONValueForKey("foo") var foo2: Int = try json.JSONValueForKey("foo") var foo3: Int? = try json.JSONValueForKey("foo") var foo4: Int? = try json.JSONValueForKey("bar") var arr: [Int] = try json.JSONValueForKey("array") var obj: JSONObject? = try json.JSONValueForKey("object") let innerfoo: Int = try obj!.JSONValueForKey("foo") let innerfoo2: Int = try json.JSONValueForKey("object.foo") let bool: Bool = try json.JSONValueForKey("bool") let url: NSURL = try json.JSONValueForKey("url")  - 
        
jarsen revised this gist
Oct 15, 2015 . 1 changed file with 0 additions and 3 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -86,9 +86,6 @@ extension Dictionary: JSONValueType { } } extension NSURL: JSONValueType { public static func JSONValue(object: Any) throws -> NSURL { guard let urlString = object as? String, objectValue = NSURL(string: urlString) else {  - 
        
jarsen created this gist
Oct 15, 2015 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,178 @@ import Foundation // // MARK: - JSONError Type // public enum JSONError: ErrorType, CustomStringConvertible { case KeyNotFound(key: JSONKeyType) case NullValue(key: JSONKeyType) case TypeMismatch(expected: Any, actual: Any) case TypeMismatchWithKey(key: JSONKeyType, expected: Any, actual: Any) public var description: String { switch self { case let .KeyNotFound(key): return "Key not found: \(key.stringValue)" case let .NullValue(key): return "Null Value found at: \(key.stringValue)" case let .TypeMismatch(expected, actual): return "Type mismatch. Expected type \(expected). Got '\(actual)'" case let .TypeMismatchWithKey(key, expected, actual): return "Type mismatch. Expected type \(expected) at key: \(key). Got '\(actual)'" } } } // // MARK: - JSONKeyType // public protocol JSONKeyType: Hashable { var stringValue: String { get } } extension String: JSONKeyType { public var stringValue: String { return self } } // // MARK: - JSONValueType // public protocol JSONValueType { typealias _JSONValue = Self static func JSONValue(object: Any) throws -> _JSONValue } extension JSONValueType { public static func JSONValue(object: Any) throws -> _JSONValue { guard let objectValue = object as? _JSONValue else { throw JSONError.TypeMismatch(expected: JSONValue.self, actual: object.dynamicType) } return objectValue } } // // MARK: - JSONValueType Implementations // extension String: JSONValueType {} extension Int: JSONValueType {} extension UInt: JSONValueType {} extension Float: JSONValueType {} extension Double: JSONValueType {} extension Bool: JSONValueType {} extension Array where Element: JSONValueType { public static func JSONValue(object: Any) throws -> [Element] { guard let objectValue = object as? [Element] else { throw JSONError.TypeMismatch(expected: self, actual: object.dynamicType) } return objectValue } } extension Dictionary: JSONValueType { public static func JSONValue(object: Any) throws -> [Key: Value] { guard let objectValue = object as? [Key: Value] else { throw JSONError.TypeMismatch(expected: self, actual: object.dynamicType) } return objectValue } } // MARK: - // MARK: JSONObject NSURL Support extension NSURL: JSONValueType { public static func JSONValue(object: Any) throws -> NSURL { guard let urlString = object as? String, objectValue = NSURL(string: urlString) else { throw JSONError.TypeMismatch(expected: self, actual: object.dynamicType) } return objectValue } } // // MARK: - JSONObject // public typealias JSONObject = [String: AnyObject] extension Dictionary where Key: JSONKeyType { private func anyForKey(key: Key) throws -> Any { let pathComponents = key.stringValue.characters.split(".").map(String.init) var accumulator: Any = self for component in pathComponents { if let componentData = accumulator as? [Key: Value], value = componentData[component as! Key] { accumulator = value continue } throw JSONError.KeyNotFound(key: key) } return accumulator } public func JSONValueForKey<A: JSONValueType>(key: Key) throws -> A { let any = try anyForKey(key) guard let result = try A.JSONValue(any) as? A else { throw JSONError.TypeMismatchWithKey(key: key, expected: A.self, actual: any.dynamicType) } if let _ = result as? NSNull { throw JSONError.NullValue(key: key) } return result } public func JSONValueForKey<A: JSONValueType>(key: Key) throws -> [A] { let any = try anyForKey(key) return try Array<A>.JSONValue(any) } public func JSONOptionalForKey<A: JSONValueType>(key: Key) throws -> A? { do { return try self.JSONValueForKey(key) as A } catch JSONError.KeyNotFound { return nil } catch JSONError.NullValue { return nil } catch { throw error } } } // // MARK: - Tests // var json: JSONObject = ["url": "http://apple.com", "foo": (2 as NSNumber), "str": "Hello, World!", "array": [1,2,3,4,7], "object": ["foo": (3 as NSNumber), "str": "Hello, World!"], "bool": (true as NSNumber)] do { var str: String = try json.JSONValueForKey("str") // var foo1: String = try json.JSONValueForKey("foo") var foo2: Int = try json.JSONValueForKey("foo") var foo3: Int? = try json.JSONOptionalForKey("foo") var foo4: Int? = try json.JSONOptionalForKey("bar") var arr: [Int] = try json.JSONValueForKey("array") var obj: JSONObject = try json.JSONValueForKey("object") let innerfoo: Int = try obj.JSONValueForKey("foo") let innerfoo2: Int = try json.JSONValueForKey("object.foo") let bool: Bool = try json.JSONValueForKey("bool") let url: NSURL = try json.JSONValueForKey("url") } catch { print("\(error)") }