美文网首页GitHub 中文社区iosiOS Developer
【译】SwiftyJSON 中文文档翻译

【译】SwiftyJSON 中文文档翻译

作者: HideOnBush | 来源:发表于2017-02-13 15:13 被阅读229次

    前言

    最近正在编写 iOS APP 的后台接口,调试的时候要解析JSON数据,所以就来学习使用 SwiftyJSON 这个第三方库,但网上搜的资料感觉写的都不怎么样,最后就只能硬着头皮看官方的文档了,尝试着翻译,借此机会学习并且提高一下自己的 English 水平吧。Let's GO. (PS: 虽然官网也有中文翻译,但是好像不是很全。。。。。😆).如果有翻译错误❎,请见谅也请指出,谢谢!

    SwiftyJSON 使得在 Swift 下处理 JSON 数据变得非常容易。

    1. [为什么在 Swift 下处理 JSON 数据的方式不是很好](#为什么在 Swift 下处理 JSON 数据的方式不是很好)
    2. 需求
    3. 整合
    4. 用法
    5. [和 Alamofire 一起使用](#和 Alamofire 一起使用)

    为什么在 Swift 下处理 JSON 数据的方式不是很好

    Swift 是一种严格的类型安全的语言。尽管明确的类型有利于我们减少错误,但是当我们在处理 JSON 和 其他隐式数据类型的时候就变得很痛苦。

    拿 Twitter API 举个栗子。我将在 Swift 的下取回一个用户的 “名字”(根据 Twitter 的 API https://dev.twitter.com/docs/api/1.1/get/statuses/home_timeline)。

    代码是这样子的:

    if let statusesArray = try? JSONSerialization.jsonObject(with: data, options: .allowFragments) as? [[String: Any]],
        let user = statusesArray[0]["user"] as? [String: Any],
        let username = user["name"] as? String {
        // Finally we got the username
    }
    

    这样不是很好。

    即使我们使用可选绑定,看起来也是一团糟:

    if let JSONObject = try JSONSerialization.jsonObject(with: data, options: .allowFragments) as? [[String: Any]],
        let username = (JSONObject[0]["user"] as? [String: Any])?["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
    }
    

    并且你也不用担心可选类型拆包。这些都是自动帮你完成。

    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 current Optional String type with safety
    } else {
      //print the error
      print(json[999999]["wrong_ket"]["wrong_name"])
    }
    

    需求

    • iOS 8.0+ | macOS 10.10+|watch 2.0+

    • Xcode 8

    整合

    CocoaPods(iOS 8+, OS X 10.9+)

    你可以使用 CocoaPods 来 安装 SwiftyJSON ,只要把一下的添加到 Podfile :

    platform :iOS, '8.0'
    use_frameworks!
    
    target 'YourAPPName' do
    pod 'SwiftyJSON'
    end
    

    注意这需要 CocoaPods 版本 36,并且你的 iOS 开发版本至少是 8.0:

    Carthage(iOS 8+,OS X 10.9+)

    你可以通过使用 Cathage 来安装 SwiftyJSON ,只需把一下的添加到 Cartfile:

    github "SwiftyJOSN/SwiftyJSON"
    
    Swift Package Manager

    你可以使用 The Swift Package Manager 来安装 SwiftyJSON ,只需添加合适的描述到你的 Package.swift 文件:

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

    注意, Swift Package Manager 任然处于早期设计和开发阶段,更多信息请查看 GitHub Page

    手动添加(iOS7+,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.data(using: .utf8, allowLossyConversion: false) {
      let json = JSON(data: dataFromString)
    }
    
    下标
    //从 JSON数组 中获取一个 double
    let name = json[0].double
    
    //从一个 JSON数组 里获取一个 字符串数组
    let arrayNames = json["users"].arrayValue.map({$0["name"].stringValue})
    
    //从一个 JSON字典 中获取一个 string
    let name = json["name"].stringValue
    
    //通过元素的路径来获取 string
    let path: [JSONSubscriptType] = [1, "list", 2, "name"]
    let name = json[path].string
    //同样的
    let name = json[1]["list"][2]["name"].string
    //或者
    let name = json[1, "list", 2, "name"].string
    
    //条件苛刻的情况
    let name = json[].string
    
    //普通的方法
    let keys: [SubscriptType] = [1, "list", 2, "name"]
    let name = json[keys].string
    
    循环
    //如果 JSON 是字典
    for (key, subJson):(String, JSON) in json {
      //做你想做的事情
    }
    

    即使 JSON 是数组,第一个元素也总是字符串。

    //如果 JSON是数组
    //index 是0到JSON数量的一个字符串值
    for (index, subJson):(String, JSON) in json {
      //做你想做的事情
    }
    
    错误

    使用下标来获取或设置字典或数组里的一个值

    如果 JSON 是:

    • 一个数组,应用可能奔溃由于数组越界。
    • 一个字典,它将返回 nil 并且没有原因。
    • 不是字典或者数组,应用可能因为“不认识选择器”而奔溃。

    这些在 SwiftyJSON 中都不会发生。

    let json = JSON(["name", "age"])
    if let name = json[999].string {
      //做你想做的事情
    } else {
      print(json[999].error)//"Array[999] 已经越界了"
    }
    
    let json = JSON(["name":"Jack", "age": 25])
    if let name = json["address"].string {
      //做你想做的事情
    } else {
      print(json["address"].error)//"Dictionary["address"]并不存在"
    }
    
    let json = JSON(12345)
    if let age = json[0].string {
      //做你想做的事情
    } else {
      print(json[0]) // "Array[0] 失败,这不是一个数组"
      print(json[0].error) // "Array[0] 失败, 这不是一个数组"
    }
    
    if let name = json["name"].string {
      //做你想做的事情
    } else {
      print(json["name"]) //"Dictionary[\"name"] 失败, 这不是一个字典"
      print(json["name"].error) //"Dictionary[\"name"] 失败,这不是一个字典"
    }
    
    Optional getter
    //数字
    if let id = json["user"]["favourites_count"].number {
      //做你想做的事情
    } else {
      //打印错误
      print(json["user"]["favourites_count"].error)
    }
    
    //字符串
    if let id = json["user"]["name"].string {
      //做你想做的事情
    } else {
      //打印错误
      print(json["user"]["name"])
    }
    
    //bool
    if let id = json["user"]["is_translator"].bool {
      //做你想做的事情
    } else {
      //打印错误
      print(json["user"]["is_translator"])
    }
    
    //整型
    if let id = json["user"]["id"].int {
      //做你想做的事情
    } else {
      //打印错误
      print(json["user"]["id"])
    }
    ...
    
    Non-optional getter

    非可选 getter 名为 xxxValue

    //如果不是数字或者空,返回 0
    let id : Int = json["id"].intValue
    
    //如果不是字符串或者空,返回 ""
    let name: String = json["name"].stringValue
    
    //如果不是数组或者空,返回 []
    let list: Array<JSON> = json["list"].arrayValue
    
     //如果不是字典或者空,返回 [:]
     let user: Dictionary<String, JSON> = json["user"].dictionaryValue
    
    setter
    json["name"] = JSON("new-name")
    json[0] = JSON(1)
    
    json["id"].int = 1234567890
    json["coordinate"].double = 9766.766
    json["name"].string = "jack"
    json.arrayObject = [1, 2, 3, 4]
    json.dictionaryObject = ["name" : "Jack", "age" : 25]
    
    元对象
    let jsonObject: Any = json.object
    
    if let jsonObject: Any = json.rawValue
    
    //把 JSON 转化为字符串元
    if let data = json.rawData() {
      //做你想做的事情
    }
    
    //把 字符串元转化为 JSON
    if let string = json.rawString() {
      //做你想做的事情
    }
    
    存在性
    //用来显示 JSON 中是否有指定的值
    if json["name"].exist()
    
    文字转换

    更多关于文字转换的信息:Swift Literal Convertibles

    //字符串转换
    let json: JSON = "I'm a json"
    
    //整型转换
    let json: JSON = 1234
    
    //Bool型转换
    let json: JSON = true
    
    //单精度浮点数转换
    let json: JSON = 2.8756
    
    //字典转换
    let json: JSON = ["I" : "am", "a" : "json"]
    
    //数组转换
    let json: JSON = ["I", "am", "a", "json"]
    
    //空转换
    let json: JSON = nil
    
    //带有下标的数组
    var json: JSON = [1, 2, 3]
    json[0] = 100
    json[1] = 200
    json[3] = 300
    json[999] = 300 //别担心, 什么都不会发生
    
    //带有下标的字典
    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: [JSONSubscriptType] = ["list", 3, "what"]
    jaon[path] = "that"
    
    //带有其他的 JSON 对象
    let user: JSON = ["username" : "Strve", "password" : "supersecurepassword"]
    let auth: JSON = [
      "user": user.object //使用 user.object 替代 user
      "apikey": "supersecuretapitoken"
    ]
    
    合并

    把一个 JSON 与另外一个 JSON 合并是可能的。合并两个 JSON 会把原始 JSON 中不存在的只出现在另外一个 JSON 中的数据添加进来。

    如果两个 JSON 包含了的值有相同的键,通常情况下会重写原JSON的值,但是有两种情况下会有特别的处理:

    • 在两个值都是JSON.Type.array 的情况下,值形成在另一个JSON中的数组,附加到原始JSON的数组值。
    • 在两个值都是 JSON.Type.dictionary 的情况下,两个JSON值都以合并封装JSON的相同方式合并。

    在JSON中的两个字段具有不同类型的情况下,值将始终被覆盖。

    有两种不同的方式合并: merge 修改原始的 JSON ,而合并在副本上以非破坏性方式工作。

    let original: JSON = [
        "first_name": "John",
        "age": 20,
        "skills": ["Coding", "Reading"],
        "address": [
            "street": "Front St",
            "zip": "12345",
        ]
    ]
    
    let update: JSON = [
        "last_name": "Doe",
        "age": 21,
        "skills": ["Writing"],
        "address": [
            "zip": "12342",
            "city": "New York City"
        ]
    ]
    
    let updated = original.merge(with: update)
    // [
    //     "first_name": "John",
    //     "last_name": "Doe",
    //     "age": 21,
    //     "skills": ["Coding", "Reading", "Writing"],
    //     "address": [
    //         "street": "Front St",
    //         "zip": "12342",
    //         "city": "New York City"
    //     ]
    // ]
    
    
    文字表示

    有两种可选可以用:

    • 使用 Swift 默认的
    • 使用一个自定义的,可以很好地处理可选项,并将 nil 表示为 “null” :
    let dict = ["1":2, "2":"two", "3": nil] as [String: Any?]
    let json = JSON(dict)
    let representation = json.rawString(options: [.castNilToNSNull: true])
    // representation is "{\"1\":2,\"2\":\"two\",\"3\":null}", which represents {"1":2,"2":"two","3":null}
    

    和 Alamofire 一起使用

    SWiftyJSON 很好地包装了 Alamofire JSON 相应的结果:

    Alamofire.request(url, mothod: .get).validate().responseJSON {
      response in
      switch response.result {
        case .success(let value):
            let json = JSON(value)
            print("JSON:\(json)")
        case .failure(let error):
            print(error)
      }
    }
    

    相关文章

      网友评论

        本文标题:【译】SwiftyJSON 中文文档翻译

        本文链接:https://www.haomeiwen.com/subject/nfftwttx.html