Last active
May 27, 2016 06:25
-
-
Save kittinunf/8ad8ac9ae530b88a989a9363d33d66f5 to your computer and use it in GitHub Desktop.
JsonParser
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 characters
struct Error : ErrorType { | |
let message: String | |
} | |
struct Json { | |
let dictionary: [String : AnyObject] | |
init?(dictionary: [String : AnyObject]?) { | |
guard let dictionary = dictionary else { return nil } | |
self.dictionary = dictionary | |
} | |
func get<T, U>(key: String, transformer: T -> U?) throws -> U { | |
let gotOptional = dictionary[key] | |
guard let got = gotOptional else { throw Error(message: "Key: \(key) is not found.") } | |
guard let typed = got as? T else { throw Error(message: "Key: \(key) was wrong type. Value is \(got)") } | |
guard let transformed = transformer(typed) else { throw Error(message: "Key: \(key), Value: \(typed) cannot be transformed") } | |
return transformed | |
} | |
func get<T>(key: String) throws -> T { | |
return try get(key, transformer: { $0 as T }) | |
} | |
func getOptional<T, U>(key: String, transformer: T -> U?) throws -> U? { | |
let gotOptional = dictionary[key] | |
guard let got = gotOptional else { return nil } | |
guard let typed = got as? T else { throw Error(message: "Key: \(key) was wrong type. Value is \(got)") } | |
guard let transformed = transformer(typed) else { throw Error(message: "Key: \(key), Value: \(typed) cannot be transformed") } | |
return transformed | |
} | |
func getOptional<T>(key: String) -> T? { | |
do { | |
return try getOptional(key, transformer: { $0 as T }) | |
} catch { | |
return nil | |
} | |
} | |
func getArray<T, U>(key: String, transformer: T -> U?) throws -> [U] { | |
let got: [T] = try get(key) | |
return got.flatMap(transformer) | |
} | |
} | |
enum Gender: String { | |
case Male = "M" | |
case Female = "F" | |
} | |
struct Dog { | |
let name: String | |
} | |
struct Person { | |
let name: String | |
let age: Int | |
let gender: Gender | |
let dogs: [Dog] | |
let optional: String? | |
init?(dictionary: [String: AnyObject]?) { | |
guard let dictionary = dictionary, json = Json(dictionary: dictionary) else { return nil } | |
do { | |
name = try json.get("name") | |
age = try json.get("age") | |
gender = try json.get("gender") { Gender(rawValue: $0) } | |
dogs = try json.getArray("dogs") { Dog(name: $0) } | |
optional = json.getOptional("foo") | |
} catch let error { | |
print(error) | |
return nil | |
} | |
} | |
} | |
var jsonDict = [String: AnyObject]() | |
jsonDict["name"] = "Adam" as? AnyObject | |
jsonDict["age"] = 32 as? AnyObject | |
jsonDict["gender"] = "M" as? AnyObject | |
jsonDict["dogs"] = ["Robert", "Fido", "Zolo"] as? AnyObject | |
print(jsonDict) | |
let person = Person(dictionary: jsonDict) | |
if let person = person { | |
print(person.name) | |
print(person.age) | |
print(person.gender) | |
print(person.dogs) | |
print(person.optional) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment