Skip to content

Instantly share code, notes, and snippets.

@kittinunf
Last active May 27, 2016 06:25
Show Gist options
  • Save kittinunf/8ad8ac9ae530b88a989a9363d33d66f5 to your computer and use it in GitHub Desktop.
Save kittinunf/8ad8ac9ae530b88a989a9363d33d66f5 to your computer and use it in GitHub Desktop.
JsonParser
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