Skip to content

Instantly share code, notes, and snippets.

@ElvishJerricco
Last active August 29, 2015 14:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ElvishJerricco/290dd0fdeb99494725eb to your computer and use it in GitHub Desktop.
Save ElvishJerricco/290dd0fdeb99494725eb to your computer and use it in GitHub Desktop.
JSON
import Foundation
enum JSON {
case JString(String)
case JNumber(Double)
case JBool(Bool)
case JArray([JSON])
case JObject([String: JSON])
case Null
}
extension JSON {
static func from(obj: AnyObject) -> JSON {
if let str = obj as? String {
return .JString(str)
} else if let n = obj as? Double {
return .JNumber(n)
} else if let b = obj as? Bool {
return .JBool(b)
} else if let arr = obj as? [AnyObject] {
return .JArray(arr.map(from))
} else if let dict = obj as? [String: AnyObject] {
var newDict = [String: JSON]()
for (k,v) in dict {
newDict[k] = from(v)
}
return .JObject(newDict)
} else {
return .Null
}
}
}
extension JSON: NilLiteralConvertible {
static func convertFromNilLiteral() -> JSON {
return .Null
}
}
extension JSON {
subscript (str: String) -> JSON {
get {
switch self {
case .JObject(let dict):
return dict[str] ?? .Null
default:
return .Null
}
}
}
subscript (i: Int) -> JSON {
get {
switch self {
case .JArray(let arr):
return arr[i]
default:
return .Null
}
}
}
}
extension JSON {
var string: String? {
get {
switch self {
case .JString(let str):
return str
default:
return nil
}
}
}
var number: Double? {
get {
switch self {
case .JNumber(let n):
return n
default:
return nil
}
}
}
var bool: Bool? {
get {
switch self {
case .JBool(let b):
return b
default:
return nil
}
}
}
}
protocol JSONModel {
class func createFromJSON(json: JSON) -> Self?
}
extension JSON {
static func model<M: JSONModel>(data: NSData) -> M? {
var error: NSError?
let object: AnyObject! = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: &error)
assert(error == nil)
return M.createFromJSON(JSON.from(object))
}
}
class ExampleModel: JSONModel {
let name: String
var email: String?
required init(name: String, email: String?) {
self.name = name
self.email = email
}
class func createFromJSON(json: JSON) -> Self? {
return self(name: json["name"].string!, email: json["email"].string)
}
}
let jsonData = ("{\"name\":\"John\", \"email\":\"hey@mail.com\"}" as NSString).dataUsingEncoding(NSUTF8StringEncoding)!
let model: MyModel? = JSON.model(jsonData)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment