如何使用 Coadable 从字典中解码 .keys

How to decode .keys from dictionary using Coadable

我的回复低于 JSON。我想使用 .keys 方法获取“数据”的所有键,即 [“规则”、“偏好”、“目标”]。但是我无法使用 .keys 功能获取所有键的数组。我也附上了我的代码片段。如果你遇到过这个问题,请建议我解决这个问题。

不过,我可以使用 ObjectMapper 和本机 Dictionary 对象获取这些 allKeys。我只需要知道为什么我无法使用 Codable 实现此目的。

我的 json 回复

{
    "statusCode": 200,
    "status": "success",
    "message": null,
    "data": {
        "rules": {
            "goals": {
                "min": "1",
                "max": "3"
            }
        },
        "preference": [
            1,
            2,
            3
        ],
        "goals": {
            "total": 4,

            "data": []
        }
    }
}

我的代码片段:

struct MeetingsDataModal: Codable {
    let statusCode: Int?
    let status: String?
    let message: String?
    let data: Results?
    enum CodingKeys: String, CodingKey {
        case statusCode = "statusCode"
        case status = "status"
        case message = "message"
        case data = "data"
    }
    func allkeys() {

    }
}

struct Results : Codable {
    let rules: Rules?
    let preference: [Preference]?
    let goals: Goals?
    enum CodingKeys: String, CodingKey {
        case rules = "rules"
        case preference = "preference"
        case goals = "goals"
    }
}

struct Rules : Codable {
}
struct Preference : Codable {
}
struct Goals : Codable {
}

我的期望

let content = try JSONDecoder().decode(MeetingsDataModal.self, from: (response as? Data)!)
print(content.data.keys)

但是我得到了,

Value of type 'Results?' has no member 'keys'

如果您确实需要 .keys。可以添加两行代码:

   struct Results : Codable {
        let rules: Rules?
        let preference: [Preference]?
        let goals: Goals?
        enum CodingKeys: String, CodingKey {
            case rules = "rules"
            case preference = "preference"
            case goals = "goals"
        }

        var keys : [String]{
            return["rules", "preference","goals"]
        }
    }

实际上,如果您不喜欢 encoding/decoding 方式,我们还有另一个传统的 JSON 对象可以帮助您处理非结构化 JSON.

    let obj =   try JSONSerialization.jsonObject(with: response!, options: JSONSerialization.ReadingOptions.allowFragments)

    print((((obj as! [String: Any?])["data"]) as! [String: Any?]).keys)

这是一种解码数据结构的方法。

           let d = """
        {
            "statusCode": 200,
            "status": "success",
            "message": null,
            "data": {
                "rules": {
                    "goals": {
                        "min": "1",
                        "max": "3"
                    }
                },
                "preference": [
                1,
                2,
                3
                ],
                "goals": {
                    "total": 4,

                    "data": []
                }
            }
        }
        """.data(using: .utf8)!


        struct MeetingsDataModal: Decodable {
            let statusCode: Int
            let status: String
            let message: String?
            let data: Results
        }

        struct Results : Decodable {
            let rules: Rules
            let preference: [Int]
            let goals: Goals
        }

        struct Rules : Decodable {
            let goals : DirectData
        }
        struct DirectData : Decodable{
            let min : String
            let max : String
        }
        struct Goals : Decodable {
            let total : Int
            let data : [String]
        }

        let data0 = try JSONDecoder().decode(MeetingsDataModal.self, from: d)
        print(data0)

也许我不太理解这个问题,但是您的 "keys" 是由您的 Codable 协议定义的 - 所以它们是已知的。如果您使用 Swift 4.2+,您可以利用 CaseIterable 协议

struct Results: Codable {
    let testOne: Int
    let testTwo: String
    enum CodingKeys: String, CodingKey, CaseIterable {
        case testOne
        case testTwo
    }
}

Results.CodingKeys.allCases.map { [=10=].rawValue }