Freddy
suggest changeFreddy is a JSON parsing library maintained by Big Nerd Ranch. It has three principal benefits:
- Type Safety: Helps you work with sending and receiving JSON in a way that prevents runtime crashes.
- Idiomatic: Takes advantage of Swift’s generics, enumerations, and functional features, without complicated documentation or magical custom operators.
- Error Handling: Provides informative error information for commonly occurring JSON errors.
Example JSON Data
Let’s define some example JSON data for use with these examples.
{"success": true,"people": [{"name": "Matt Mathias","age": 32,"spouse": true},{"name": "Sergeant Pepper","age": 25,"spouse": false}],"jobs": ["teacher","judge"],"states": {"Georgia": [30301,30302,30303],"Wisconsin": [53000,53001]}}
let jsonString = "{\"success\": true, \"people\": [{\"name\": \"Matt Mathias\",\"age\": 32,\"spouse\": true},{\"name\": \"Sergeant Pepper\",\"age\": 25,\"spouse\": false}],\"jobs\": [\"teacher\",\"judge\"],\"states\": {\"Georgia\": [30301,30302,30303],\"Wisconsin\": [53000,53001]}}"
let jsonData = jsonString.dataUsingEncoding(NSUTF8StringEncoding)!
Deserializing Raw Data
To deserialize the data, we initialize a JSON
object then access a particular key.
do {
let json = try JSON(data: jsonData)
let success = try json.bool("success")
} catch {
// do something with the error
}
We try
here because accessing the json
for the key "success"
could fail–it might not exist, or the value might not be a boolean.
We can also specify a path to access elements nested in the JSON structure. The path is a comma-separated list of keys and indices that describe the path to a value of interest.
do {
let json = try JSON(data: jsonData)
let georgiaZipCodes = try json.array("states", "Georgia")
let firstPersonName = try json.string("people", 0, "name")
} catch {
// do something with the error
}
Deserializing Models Directly
JSON can be directly parsed to a model class that implements the JSONDecodable
protocol.
public struct Person {
public let name: String
public let age: Int
public let spouse: Bool
}
extension Person: JSONDecodable {
public init(json: JSON) throws {
name = try json.string("name")
age = try json.int("age")
spouse = try json.bool("spouse")
}
}
do {
let json = try JSON(data: jsonData)
let people = try json.arrayOf("people", type: Person.self)
} catch {
// do something with the error
}
Serializing Raw Data
Any JSON
value can be serialized directly to NSData
.
let success = JSON.Bool(false)
let data: NSData = try success.serialize()
Serializing Models Directly
Any model class that implements the JSONEncodable
protocol can be serialized directly to NSData
.
extension Person: JSONEncodable {
public func toJSON() -> JSON {
return .Dictionary([
"name": .String(name),
"age": .Int(age),
"spouse": .Bool(spouse)
])
}
}
let newPerson = Person(name: "Glenn", age: 23, spouse: true)
let data: NSData = try newPerson.toJSON().serialize()