swift - 使用 jSONEncoder 的自定义结构

标签 swift serialization encodable jsonencoder

想使用 JSONEncoder+Encodable 将对象编码成自定义结构。

struct Foo: Encodable {
   var name: String?
   var bars: [Bar]?
}

struct Bar: Encodable {
   var name: String?
   var value: String?
}

let bar1 = Bar(name: "bar1", value: "barvalue1")
let bar2 = Bar(name: "bar2", value: "barvalue2")
let foo = Foo(name: "foovalue", bars: [bar1, bar2])

foo 编码的默认方法给出:

let encoder = JSONEncoder()
encoder.outputFormatting = .prettyPrinted
let data = try encoder.encode(foo)
print(String(data: data, encoding: .utf8)!)

输出:

{
   "name": "foovalue",
   "bars": [
      {
         "name": "bar1",
         "value": "barvalue1"
      },
      {
         "name": "bar2",
         "value": "barvalue2"
      }
   ]
}

在自定义输出中,我想使用属性 name 的值作为键,rest 的值作为上述键的值。这同样适用于嵌套对象。所以我希望输出是:

{
    "foovalue": [
       {
          "bar1": "barvalue1"
       },
       {
          "bar2": "barvalue2"
       }
     ]
}

问题是 Encodable/JSONEncoder 是否支持这个。现在我只处理第一个输出字典并通过迭代键来重构它。

最佳答案

如果你想保留 FooBar Encodable,你可以通过提供一个自定义的 encode(to :) 使用特定编码键,其值为 name:

private struct StringKey: CodingKey {
    let stringValue: String
    var intValue: Int? { return nil }
    init(_ string: String) { stringValue = string }
    init?(stringValue: String) { self.init(stringValue) }
    init?(intValue: Int) { return nil }
}

struct Foo: Encodable {
    var name: String
    var bars: [Bar]

    func encode(to encoder: Encoder) throws {
        var container = encoder.container(keyedBy: StringKey.self)
        try container.encode(bars, forKey: StringKey(name))
    }
}

struct Bar : Encodable {
    var name: String
    var value: String

    func encode(to encoder: Encoder) throws {
        var container = encoder.container(keyedBy: StringKey.self)
        try container.encode(value, forKey: StringKey(name))
    }
}

StringKey 可以接受任何 String 值,允许您根据需要任意编码。

关于swift - 使用 jSONEncoder 的自定义结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48718091/

相关文章:

ios - UIDatePicker 与伊斯兰历的奇怪行为

c# - 将对象列表转换为 json 数组

swift - 将 JSON 编码器与 Codable 类型的计算变量结合使用

swift - 仅类协议(protocol)作为具有 AnyObject 约束的关联类型的类型别名

ios - 从 iOS 中的联系方式获取街道、城市、州、 zip 和国家/地区并填充到标签

swift - 在 Swift 字符串文字中转义反斜杠

C# 反序列化列表计数为零

c# - 在 C# 中序列化和反序列化自定义异常

ios - swift 可编码 : How to encode top-level data into nested container

dictionary - 编码一个 [String : Encodable] dictionary into JSON using JSONEncoder in Swift 4