Last active
August 29, 2015 14:02
-
-
Save jparishy/9f9eddf7ddc60372014b to your computer and use it in GitHub Desktop.
Abusing Swift Enums for easier JSON parsing
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
/* | |
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 |
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
// | |
// 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