Skip to content

Instantly share code, notes, and snippets.

@jparishy
Last active August 29, 2015 14:02
Show Gist options
  • Save jparishy/9f9eddf7ddc60372014b to your computer and use it in GitHub Desktop.
Save jparishy/9f9eddf7ddc60372014b to your computer and use it in GitHub Desktop.
Abusing Swift Enums for easier JSON parsing
/*
data.json
[
{
"name": {
"first": "Julius",
"last": "Parishy"
},
"hobbies": [
"programming",
"longboarding",
"fishing",
"listening to the rap music"
]
}
]
*/
var data = NSData(contentsOfFile: NSBundle.mainBundle().pathForResource("data", ofType: "json"))
var error: NSError?
if let json = JSON.parse(data, error: &error) {
let first = json[0]
println(first["name"]["first"].stringValue)
} else {
println("Failed to parse JSON")
}
// Outputs: Julius
//
// JSON.swift
// JSON
//
// Created by Julius Parishy on 6/5/14.
// Copyright (c) 2014 jp. All rights reserved.
//
import Foundation
enum JSON {
case IntValue(Int)
case StringValue(String)
case ArrayValue(Array<JSON>)
case DictionaryValue(Dictionary<String, JSON>)
case NullValue
subscript(index: Int) -> JSON {
switch self {
case let .ArrayValue(arr):
return arr[index]
default:
return NullValue
}
}
subscript(key: String) -> JSON {
switch self {
case let .DictionaryValue(dict):
if let value = dict[key] {
return value
} else {
return NullValue
}
default:
return NullValue
}
}
var integerValue: Int? {
switch self {
case let .IntValue(i):
return i
default:
return nil
}
}
var stringValue: String? {
switch self {
case let .StringValue(str):
return str
default:
return nil
}
}
var arrayValue: Array<JSON>? {
switch self {
case let .ArrayValue(arr):
return arr
default:
return nil
}
}
var dictionaryValue: Dictionary<String, JSON>? {
switch self {
case let .DictionaryValue(dict):
return dict
default:
return nil
}
}
static func parse(data: NSData, error: NSErrorPointer) -> JSON? {
var serializationError: NSError?
let JSONObject: AnyObject? = NSJSONSerialization.JSONObjectWithData(data, options: nil, error: &serializationError)
if !JSONObject {
if serializationError {
return nil
}
}
if JSONObject is NSDictionary {
return bridgeJSONObject(JSONObject)
} else if JSONObject is NSArray {
return bridgeJSONObject(JSONObject)
} else {
return nil
}
}
static func bridgeJSONObject(object: AnyObject?) -> JSON {
if object is NSNumber {
let numberObject = object as NSNumber
return JSON.IntValue(numberObject.integerValue)
} else if object is NSString {
let stringObject = object as NSString
return JSON.StringValue(stringObject)
} else if object is NSArray {
var arrayValue = Array<JSON>()
for obj: AnyObject in object as NSArray {
let jsonObj = bridgeJSONObject(obj)
arrayValue.append(jsonObj)
}
return JSON.ArrayValue(arrayValue)
} else if object is NSDictionary {
var dictionaryValue = Dictionary<String, JSON>()
for (key: AnyObject, value: AnyObject) in object as NSDictionary {
let jsonValue = bridgeJSONObject(value)
let stringKey = key as String
dictionaryValue[stringKey] = jsonValue
}
return JSON.DictionaryValue(dictionaryValue)
} else {
return NullValue
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment