【问题标题】:Decode an array inside JSON data only using Swift 4 Codable仅使用 Swift 4 Codable 解码 JSON 数据中的数组
【发布时间】:2018-03-18 18:22:41
【问题描述】:

我正在使用 Swift 4 Codable,我正在从我的网络服务接收这个 JSON:

{
    "status": "success",
    "data": {
        "time": "00:02:00",
        "employees": [
            {
                "id": 001,
                "name": "foo"
            }, 
            {
                "id": 002,
                "name": "bar"
            }
        ]
    }
}

我只想将员工数组解码为员工对象(时间属性只会保存一次),但没有任何效果。
我阅读了很多关于 Swift 4 Codable 的资料,但不知道如何解码这个数组。

编辑:我的员工类:

import Foundation

struct Employee: Codable {
    var id: Int
    var time: Date

    enum CodingKeys: String, CodingKey {
        case id = "id"
        case time = "time"
    }
}

请求:

  Alamofire.SessionManager.default.request(Router.syncUsers)
            .validate(contentType: ["application/json"])
            .responseJSON { response in
                if response.response?.statusCode == 200 {
        guard let jsonDict = response as? Dictionary<String, Any>,
                    let feedPage = Employee(from: jsonDict as! Decoder) else {
                    return
                }

                guard let response = response.result.value as? [String: Any] else {
                    return
                }

                guard let data = response["data"] as? [String: Any] else {
                    return
                }

                guard let users = data["employees"] else {
                    return
                }

                guard let usersData = try? JSONSerialization.data(withJSONObject: users, options: .prettyPrinted) else {
                    return
                }

                guard let decoded = try? JSONSerialization.jsonObject(with: usersData, options: []) else {
                    return
                }

                let decoder = JSONDecoder()

                guard let employee = try? decoder.decode(Employee.self, from: usersData) else {
                    print("errorMessage")
                    return
                }
                } else {
                    print("errorMessage")
                }
        }

【问题讨论】:

  • 您是否真的查看了您的代码和问题中的 JSON 响应?当您的示例响应显示一个名为 employees 的键时,您显然正在响应中寻找一个名为 users 的键。此外,您的方法显然是错误的。您已经使用 Alamofire 将响应解析为 JSON,然后将其中的一部分重新编码为 JSON,以便能够使用 JSONDecoder 将其从 Data 解码。这是没有意义的。要么使用 CodableJSONDecoder 以类型安全的方式解析整个 JSON,要么使用 AlamofireresponseJSON 动态解析。
  • 对不起,关键是员工...我最近更改了json。但仍然不起作用:/您能否发布该代码的解码示例。我知道这段代码没有多大意义,但我在最后一小时更改了代码并且没有成功。这是一个我知道的简单任务,但我还不能让它工作:(
  • JSON 中的数字不能以 0 开头(0 001 不是 JSON。

标签: swift swift4 codable


【解决方案1】:

使用Codable 时,如果不解码外部数据,则无法解码内部数据。

但这很简单,例如你可以省略所有的 CodingKeys。

struct Root : Decodable {
    let status : String
    let data : EmployeeData
}

struct EmployeeData : Decodable {
    let time : String
    let employees : [Employee]
}

struct Employee: Decodable {
    let id: Int
    let name: String
}

let jsonString = """
{
    "status": "success",
    "data": {
        "time": "00:02:00",
        "employees": [
            {"id": 1, "name": "foo"},
            {"id": 2, "name": "bar"}
        ]
    }
}
"""


do {
    let data = Data(jsonString.utf8)
    let result = try JSONDecoder().decode(Root.self, from: data)
    for employee in result.data.employees {
        print(employee.name, employee.id)
    }
} catch { print(error) }

【讨论】:

  • CodableDecodable/Encodable有什么区别?
  • Codable的定义是Decodable &amp; Encodable,表示两者都符合。
【解决方案2】:

您可以使用quicktype 非常轻松地解决这种 JSON 解析问题。只需在左侧粘贴您的 JSON,您将在右侧获得各种语言的类型和序列化/反序列化代码。以下是它为您的 JSON 生成的类型:

struct Employees: Codable {
    let status: String
    let data: EmployeesData
}

struct EmployeesData: Codable {
    let time: String
    let employees: [Employee]
}

struct Employee: Codable {
    let id: Int
    let name: String
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-05
    • 2018-01-09
    相关资源
    最近更新 更多