弗雷迪

Freddy 是由 Big Nerd Ranch 維護的 JSON 解析庫。它有三個主要好處:

  1. 型別安全:幫助你以防止執行時崩潰的方式傳送和接收 JSON。

  2. 慣用語:利用 Swift 的泛型,列舉和功能特性,無需複雜的文件或神奇的自定義運算子。

  3. 錯誤處理:為常見的 JSON 錯誤提供資訊性錯誤資訊。

示例 JSON 資料

讓我們定義一些示例 JSON 資料以用於這些示例。

{
  "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)!

反序列化原始資料

要反序列化資料,我們初始化 JSON 物件然後訪問特定鍵。

do {
    let json = try JSON(data: jsonData)
    let success = try json.bool("success")
} catch {
    // do something with the error
}

我們來這裡是因為訪問關鍵 successjson 可能會失敗 - 它可能不存在,或者值可能不是布林值。

我們還可以指定訪問巢狀在 JSON 結構中的元素的路徑。該路徑是以逗號分隔的鍵和索引列表,用於描述感興趣的值的路徑。

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
}

直接反序列化模型

JSON 可以直接解析為實現 JSONDecodable 協議的模型類。

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
}

序列化原始資料

任何 JSON 值都可以直接序列化到 NSData

let success = JSON.Bool(false)
let data: NSData = try success.serialize()

直接序列化模型

任何實現 JSONEncodable 協議的模型類都可以直接序列化到 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()