SwiftyJSON3 3.0.0-beta.1

SwiftyJSON3 3.0.0-beta.1

测试已测试
语言语言 SwiftSwift
授权 MIT
发布日期上次发布日期2016年9月
SPM支持 SPM

Denys Telezhkin 维护。



SwiftyJSON3 3.0.0-beta.1

  • lingoer 和 tangplin

SwiftyJSON

SwiftyJSON 使在 Swift 中处理 JSON 数据变得简单。

  1. Swift 中典型 JSON 处理方法为何不太好?
  2. 要求
  3. 集成
  4. 用例
  5. 与 Alamofire 一起使用

为了支持 Swift3,请查看 swift3 beta 分支

中文介绍

Swift 中典型 JSON 处理方法为何不太好?

Swift 对类型非常严格。尽管显式类型可以帮助我们避免错误,但是在处理 JSON 及其他天生就是隐式类型的领域时,它变得痛苦。

以 Twitter API 为例。假设我们想在 Swift 中获取某条推文的“name”值(根据 Twitter API 的 https://dev.twitter.com/docs/api/1.1/get/statuses/home_timeline)。

代码看起来是这样的

if let statusesArray = try? NSJSONSerialization.JSONObjectWithData(data, options: .AllowFragments) as? [[String: AnyObject]],
    let user = statusesArray[0]["user"] as? [String: AnyObject],
    let username = user["name"] as? String {
    // Finally we got the username
}

这样做不好。

即使是使用可选链,代码也会变得混乱

if let JSONObject = try NSJSONSerialization.JSONObjectWithData(data, options: .AllowFragments) as? [[String: AnyObject]],
    let username = (JSONObject[0]["user"] as? [String: AnyObject])?["name"] as? String {
        // There's our username
}

难以阅读的混乱——这对于实际上应该简单的事情!

使用 SwiftyJSON,您只需这样做

let json = JSON(data: dataFromNetworking)
if let userName = json[0]["user"]["name"].string {
  //Now you got your value
}

而且不用担心 Optional 包装的问题。它会自动为您完成。

let json = JSON(data: dataFromNetworking)
if let userName = json[999999]["wrong_key"]["wrong_name"].string {
    //Calm down, take it easy, the ".string" property still produces the correct Optional String type with safety
} else {
    //Print the error
    print(json[999999]["wrong_key"]["wrong_name"])
}

要求

  • iOS 7.0+ / OS X 10.9+
  • Xcode 7

集成

Swift 包管理器

您可以通过将适当的描述添加到您的 Package.swift 文件中来使用 Swift 包管理器 安装 SwiftyJSON

import PackageDescription

let package = Package(
    name: "YOUR_PROJECT_NAME",
    targets: [],
    dependencies: [
        .Package(url: "https://github.com/SwiftyJSON/SwiftyJSON.git", versions: "2.3.3" ..< Version.max)
    ]
)

请注意,Swift 包管理器 目前还处于早期设计和开发阶段,有关更多信息,请查看其 GitHub 页面

手动(iOS 7+, OS X 10.9+)

要手动在项目中使用此库,您可能需要以下步骤:

  1. 对于项目,只需将 SwiftyJSON.swift 拖到项目树中即可
  2. 对于工作区,包括整个 SwiftyJSON.xcodeproj

用例

初始化

import SwiftyJSON
let json = JSON(data: dataFromNetworking)
let json = JSON(jsonObject)
if let dataFromString = jsonString.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false) {
    let json = JSON(data: dataFromString)
}

下标

//Getting a double from a JSON Array
let name = json[0].double
//Getting a string from a JSON Dictionary
let name = json["name"].stringValue
//Getting a string using a path to the element
let path = [1,"list",2,"name"]
let name = json[path].string
//Just the same
let name = json[1]["list"][2]["name"].string
//Alternatively
let name = json[1,"list",2,"name"].string
//With a hard way
let name = json[].string
//With a custom way
let keys:[SubscriptType] = [1,"list",2,"name"]
let name = json[keys].string

循环

//If json is .Dictionary
for (key,subJson):(String, JSON) in json {
   //Do something you want
}

即使 JSON 是一个数组,第一个元素总是 String 类型

//If json is .Array
//The `index` is 0..<json.count's string value
for (index,subJson):(String, JSON) in json {
    //Do something you want
}

错误

使用下标来获取/设置数组或字典中的值

如果 JSON 是

  • 一个数组,应用可能会因为“越界”而崩溃。
  • 一个字典,它将被无原因地赋值为 nil
  • 既不是数组也不是字典,应用可能会因为“未识别的选择器”异常而崩溃。

这永远不会在 SwiftyJSON 中发生。

let json = JSON(["name", "age"])
if let name = json[999].string {
    //Do something you want
} else {
    print(json[999].error) // "Array[999] is out of bounds"
}
let json = JSON(["name":"Jack", "age": 25])
if let name = json["address"].string {
    //Do something you want
} else {
    print(json["address"].error) // "Dictionary["address"] does not exist"
}
let json = JSON(12345)
if let age = json[0].string {
    //Do something you want
} else {
    print(json[0])       // "Array[0] failure, It is not an array"
    print(json[0].error) // "Array[0] failure, It is not an array"
}

if let name = json["name"].string {
    //Do something you want
} else {
    print(json["name"])       // "Dictionary[\"name"] failure, It is not an dictionary"
    print(json["name"].error) // "Dictionary[\"name"] failure, It is not an dictionary"
}

可选获取器

//NSNumber
if let id = json["user"]["favourites_count"].number {
   //Do something you want
} else {
   //Print the error
   print(json["user"]["favourites_count"].error)
}
//String
if let id = json["user"]["name"].string {
   //Do something you want
} else {
   //Print the error
   print(json["user"]["name"])
}
//Bool
if let id = json["user"]["is_translator"].bool {
   //Do something you want
} else {
   //Print the error
   print(json["user"]["is_translator"])
}
//Int
if let id = json["user"]["id"].int {
   //Do something you want
} else {
   //Print the error
   print(json["user"]["id"])
}
...

非可选获取器

非可选获取器命名为 xxxValue

//If not a Number or nil, return 0
let id: Int = json["id"].intValue
//If not a String or nil, return ""
let name: String = json["name"].stringValue
//If not a Array or nil, return []
let list: Array<JSON> = json["list"].arrayValue
//If not a Dictionary or nil, return [:]
let user: Dictionary<String, JSON> = json["user"].dictionaryValue

设置器

json["name"] = JSON("new-name")
json[0] = JSON(1)
json["id"].int =  1234567890
json["coordinate"].double =  8766.766
json["name"].string =  "Jack"
json.arrayObject = [1,2,3,4]
json.dictionary = ["name":"Jack", "age":25]

原始对象

let jsonObject: AnyObject = json.object
if let jsonObject: AnyObject = json.rawValue
//convert the JSON to raw NSData
if let data = json.rawData() {
    //Do something you want
}
//convert the JSON to a raw String
if let string = json.rawString() {
    //Do something you want
}

存在性

//shows you whether value specified in JSON or not
if json["name"].isExists()

字面量可转换型

有关字面量可转换型的更多信息: Swift 字面量可转换型

//StringLiteralConvertible
let json: JSON = "I'm a json"
//IntegerLiteralConvertible
let json: JSON =  12345
//BooleanLiteralConvertible
let json: JSON =  true
//FloatLiteralConvertible
let json: JSON =  2.8765
//DictionaryLiteralConvertible
let json: JSON =  ["I":"am", "a":"json"]
//ArrayLiteralConvertible
let json: JSON =  ["I", "am", "a", "json"]
//NilLiteralConvertible
let json: JSON =  nil
//With subscript in array
var json: JSON =  [1,2,3]
json[0] = 100
json[1] = 200
json[2] = 300
json[999] = 300 //Don't worry, nothing will happen
//With subscript in dictionary
var json: JSON =  ["name": "Jack", "age": 25]
json["name"] = "Mike"
json["age"] = "25" //It's OK to set String
json["address"] = "L.A." // Add the "address": "L.A." in json
//Array & Dictionary
var json: JSON =  ["name": "Jack", "age": 25, "list": ["a", "b", "c", ["what": "this"]]]
json["list"][3]["what"] = "that"
json["list",3,"what"] = "that"
let path = ["list",3,"what"]
json[path] = "that"

与 Alamofire 一起工作

SwiftyJSON 可好地包装了 Alamofire JSON 响应处理程序的结果

Alamofire.request(.GET, url).validate().responseJSON { response in
    switch response.result {
    case .Success:
        if let value = response.result.value {
          let json = JSON(value)
          print("JSON: \(json)")
        }
    case .Failure(let error):
        print(error)
    }
}