【发布时间】:2021-03-02 18:01:29
【问题描述】:
需要以这样一种方式解析此 JSON,以便我应该能够访问与“项目”节点中“启用”键内的每个计划相关的好处,如下所示:
让 items = Items[0].plans.main[0].enabled[0].text
{
"MyData": {
"data": {
"benefits": {
"B1": {
"text": "Text1"
},
"B2": {
"text": "Text2"
},
"B3": {
"text": "text3"
}
}
},
"items": [
{
"plans": {
"main": [
{
"name": "plan1",
"enabled": [
"B1",
"B2"
],
"disabled": [
"B2",
"B3"
]
}
]
}
}
]
}
}
我已经尝试如下实现,但似乎这不起作用
class Main: Codable {
var name: String?
var enabled: [String]?
var disabled: [String]?
enum CodingKeys: String, CodingKey {
case name = "name"
case enabled = "enabled"
case disabled = "disabled"
}
class MyData: Codable {
var benefits: [String: Benefit]?
enum CodingKeys: String, CodingKey {
case benefits = "benefits"
}
required init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
let propertyContainer = try container.nestedContainer(keyedBy: CustomDynamicKey.self, forKey: .benefits)
self.benefits = propertyContainer.decodeValues()
}
class Benefit: Codable {
var text: String?
enum CodingKeys: String, CodingKey {
case text = "text"
}
required init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
text = try container.decode(String.self, forKey: .text)
}
}
struct CustomDynamicKey: CodingKey {
var stringValue: String
init?(stringValue: String) {
self.stringValue = stringValue
}
var intValue: Int? { return nil }
init?(intValue: Int) { return nil }
extension KeyedDecodingContainer where Key == DynamicKey {
func decodeValues() -> [String : Benefit] {
var dict = [String : Benefit]()
for key in allKeys {
if let md = try? decode(Benefit.self, forKey: key) {
dict[key.stringValue] = md
} else {
print("unsupported key")
}
}
return dict
}
}
我尝试单独解析模型。但是,我可以单独访问模型,但是在使用手动解析在所需的 init() 方法中解析 JSON 本身时,我需要将相应的好处与相应的计划进行映射。
【问题讨论】:
-
我会将它们解析为
[Sting: Benefit],在需要时为Plan提供一些逻辑。我会将该属性设为private,并使用一个函数来根据计划检索允许的属性。即,制作更高级别的功能。
标签: json swift parsing nested codable