如何使用 Codable 从字典中解码 .key
Posted
技术标签:
【中文标题】如何使用 Codable 从字典中解码 .key【英文标题】:How to decode .keys from dictionary using Coadable 【发布时间】: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
,你为什么会期待? Results
有 rules
、goals
和 preferences
,就是这样。
@luk2302 感谢您的回复。我需要获取这些 allKeys 并将其显示在表格视图的部分。其余的数组值,我需要在表格视图的行上显示。
allKeys
应该是什么?您的 JSON 和映射结构都没有这样的东西。实际预期输出是多少?
是的。我的预期输出是[“规则”、“偏好”、“目标”]。我可以在 objectMapper 中获取这些方法(.keys)。
知道Decodable
创建的是结构,而不是字典
【参考方案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)
【讨论】:
以上是关于如何使用 Codable 从字典中解码 .key的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Codable 解码具有更改键的 json 响应?