我是Swift Codable的新手,我试图编码一个"复杂的"我自己的JSON结构。这有点困难,因为它需要递归。
我找到了关于复活枚举的堆栈溢出的解决方案,但是我无法在Swift中为我的JSON实现它。 (Swift Codable protocol with recursive enums)我得到了python的解决方案,但在Swift中要复杂得多。
JSON文件将是这样的:
[
{
"id": 0,
"name": "Simple Rule A",
"operations": {
"attribute": "C",
"value": false
}
},
{
"id": 1,
"name": "Simple Rule A",
"operations": {
"ruleOperator": "AND",
"ruleOperand":[
{
"attribute": "A",
"value": false
},
{
"attribute": "C",
"value": false
}
]
}
},
{
"id": 2,
"name": "Simple Rule B",
"operations": {
"ruleOperator": "AND",
"ruleOperand":[
{"ruleOperator": "OR",
"ruleOperand":[
{
"attribute": "A",
"value": false
},
{
"attribute": "C",
"value": false
}
]
},
{
"attribute": "C",
"value": false
}
]
}
}
]
这是一个包含规则的数组,每个规则都有一个id和name以及操作。操作可以是"节点"与操作员和操作数或"叶子"作为具有属性和价值的操作数。
这就是我得到的:
import Foundation
struct Rule: Decodable {
let id: Int
let name: String
let operations: Operations
}
struct Operations {
//var ruleOperator: String
var ruleOperator: String?
var kind: Kind?
enum Kind {
case node([Operations])
case leaf(Operand)
}
init(name: String, ruleOp: String, kind: Kind) {
self.ruleOperator = ruleOp
self.kind = kind
}
}
extension Operations: Decodable {
enum CodingKeys: String, CodingKey {
case name
case ruleOperator
case nodes
case test
}
enum CodableError: Error {
case decoding(String)
case encoding(String)
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
if let someRuleOperator = try? container.decode(String.self, forKey: .ruleOperator) {
self.ruleOperator = someRuleOperator
}
if let someOperand = try container.decodeIfPresent(Operand.self, forKey: .nodes) {
self.kind = .leaf(someOperand)
}
if let array = try? container.decode([Operations].self, forKey: .nodes) {
self.kind = .node(array)
}
return
}
}
struct Operand: Decodable {
let attribute: String
let value: Bool
}
enum Operator {
case IS
case AND
case OR
case XOR
}
问题是" init(来自解码器:解码器)"部分。还有" ruleOperator:String?"作为一个可选是废话。
也许有人可以帮助我:)并给我一个正确方向的提示。
(同样不错的是如何使用操作符枚举而不是字符串,例如" IS"或" AND"。)
重写JSON结构并使用此解决方案Swift Codable protocol with recursive enums
{
"id": 1,
"name": "Simple Rule A",
"operations": [
{
"attribute": "AND",
"value": null,
"operations": [
{
"attribute": "A",
"value": true,
"operations": []
},
{
"attribute": "B",
"value": true,
"operations": []
}
]
}
]
}