Skip to content

Instantly share code, notes, and snippets.

@haldun
Created October 21, 2014 16:09
Show Gist options
  • Save haldun/c53fbf4c0011e3c1700e to your computer and use it in GitHub Desktop.
Save haldun/c53fbf4c0011e3c1700e to your computer and use it in GitHub Desktop.
my json experiments
// Playground - noun: a place where people can play
import UIKit
// Data -> JSON?
// JSON -> Cafe?
enum JSONValue {
case JSONObject([String:JSONValue])
case JSONArray([JSONValue])
case JSONString(String)
case JSONNumber(NSNumber)
case JSONBool(Bool)
case JSONNull
var object: [String:JSONValue]? {
switch self {
case .JSONObject(let value):
return value
default:
return nil
}
}
var array: [JSONValue]? {
switch self {
case .JSONArray(let value):
return value
default:
return nil
}
}
var string: String? {
switch self {
case .JSONString(let value):
return value
default:
return nil
}
}
var integer: Int? {
switch self {
case .JSONNumber(let value):
return value.integerValue
default:
return nil
}
}
var double: Double? {
switch self {
case .JSONNumber(let value):
return value.doubleValue
default:
return nil
}
}
var bool: Bool? {
switch self {
case .JSONBool(let value):
return value
case .JSONNumber(let value):
return value.boolValue
default:
return nil
}
}
subscript(i: Int) -> JSONValue? {
get {
switch self {
case .JSONArray(let value):
return value[i]
default:
return nil
}
}
}
subscript(key: String) -> JSONValue? {
get {
switch self {
case .JSONObject(let value):
return value[key]
default:
return nil
}
}
}
static func fromObject(object: AnyObject) -> JSONValue? {
switch object {
case let value as NSString:
return .JSONString(value)
case let value as NSNumber:
return .JSONNumber(value)
case let value as NSNull:
return .JSONNull
case let value as NSDictionary:
var jsonObject: [String:JSONValue] = [:]
for (k: AnyObject, v: AnyObject) in value {
if let k = k as? NSString {
if let v = JSONValue.fromObject(v) {
jsonObject[k] = v
} else {
return nil
}
}
}
return .JSONObject(jsonObject)
case let value as NSArray:
var jsonArray: [JSONValue] = []
for item in value {
if let item = JSONValue.fromObject(item) {
jsonArray.append(item)
} else {
return nil
}
}
return .JSONArray(jsonArray)
default:
return nil
}
}
}
protocol JSONSerializable {
func toJSON() -> JSONValue?
}
protocol JSONDeserializable {
class func fromJSON(value: JSONValue) -> Self?
}
final class Country: JSONSerializable, JSONDeserializable {
let name: String
init(name: String) {
self.name = name
}
func toJSON() -> JSONValue? {
return nil
}
class func fromJSON(value: JSONValue) -> Country? {
if let name = value["name"]?.string {
return Country(name: name)
}
return nil
}
}
final class Cafe: Printable, JSONSerializable, JSONDeserializable {
let id: Int
let name: String
var country: Country?
var city: String?
var zip: String?
required init(id: Int, name: String) {
self.id = id
self.name = name
}
class func fromJSON(value: JSONValue) -> Cafe? {
switch (value["id"]?.integer, value["name"]?.string) {
case (.Some(let id), .Some(let name)):
let cafe = Cafe(id: id, name: name)
cafe.city = value["city"]?.string
if let countryJson = value["country"] {
cafe.country = Country.fromJSON(countryJson)
}
return cafe
default:
return nil
}
}
class func fromJSON2(value: JSONValue) -> Cafe? {
if let id = value["id"]?.integer {
if let name = value["name"]?.string {
let cafe = Cafe(id: id, name: name)
cafe.city = value["city"]?.string
if let countryJson = value["country"] {
cafe.country = Country.fromJSON(countryJson)
}
return cafe
}
}
return nil
}
func toJSON() -> JSONValue? {
return nil
}
var description: String {
get {
return "<Cafe id:\(id), name: \(name), city: \(city), zip: \(zip), country: \(country)>"
}
}
}
let jsonString = "{\"id\":45, \"name\":\"Good Cafe\", \"city\": \"Istanbul\", \"country\": {\"name\": \"Turkei\"} }"
let jsonData = jsonString.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: true)!
var jsonError: NSError?
if let parsed: AnyObject = NSJSONSerialization.JSONObjectWithData(jsonData, options: NSJSONReadingOptions(0),
error: &jsonError) {
if let jsonObject = JSONValue.fromObject(parsed) {
if let cafe = Cafe.fromJSON(jsonObject) {
println("\(cafe.description)")
}
// if let id = jsonObject["id"]?.integer {
// println("id is \(id)")
// }
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment