【问题标题】:How to decode .keys from dictionary using Coadable如何使用 Codable 从字典中解码 .key
【发布时间】:2018-11-14 14:13:33
【问题描述】:

我有以下 JSON 响应。我想使用 .keys 方法获取“数据”的所有键,即 [“rules”、“preference”、“goals”]。但我无法使用 .keys 功能获得所有键的数组。我也附上了我的代码 sn-p。如果您遇到过这个问题,请建议我摆脱这种担忧。

虽然,我可以使用 ObjectMapper 和本机 Dictionary 对象获取这些 allKey。我只需要知道为什么我无法使用 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)

但我明白了,

“结果?”类型的值没有成员“密钥”

【问题讨论】:

  • 如果有keys,你为什么会期待? Resultsrulesgoalspreferences,就是这样。
  • @luk2302 感谢您的回复。我需要获取这些 allKeys 并将其显示在表格视图的部分。其余的数组值,我需要在表格视图的行上显示。
  • allKeys 应该是什么?您的 JSON 和映射结构都没有这样的东西。实际预期输出是多少?
  • 是的。我的预期输出是[“规则”、“偏好”、“目标”]。我可以在 objectMapper 中获取这些方法(.keys)。
  • 知道Decodable 创建的是结构,而不是字典

标签: ios json decode codable swift4.2


【解决方案1】:

也许我不太了解这个问题,但您的“密钥”是由您的 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 { $0.rawValue }

【讨论】:

    【解决方案2】:

    如果您确实需要 .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"]
            }
        }
    

    其实,如果你不喜欢编码/解码方式,我们还有一个传统的 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)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-25
      • 1970-01-01
      • 2021-12-29
      • 1970-01-01
      • 2020-01-22
      • 2021-10-15
      相关资源
      最近更新 更多