【问题标题】:Decodable that inits from an array从数组初始化的可解码
【发布时间】:2020-04-05 14:17:03
【问题描述】:

我有一个 JSON 对象数组。简而言之,它有这种形式:

[
  {"name": "Tinky Winky"},
  {"name": "Dipsy"},
  {"name": "Laa-Laa"},
  {"name": "Po"}
]

我可以创建一个结构Tubby 可以解码数组中的单个实例:

struct Tubby: Codable {
  let name: String
}

我想创建一个结构 Tubbies,它可以从 JSON 数组中解码:

struct Tubbies: Codable {
   let tubbies: [Tubby]

   init(from decoder: Decoder) throws {
     // What goes here?
     tubbies = ???
   }

……但现在我不知道应该如何解码?我只想这样做:

   init(from decoder: Decoder) throws {
     // What goes here?
     tubbies = decoder.decode([Tubby].self)
   }

Decoder 不提供decode。它有:

    /// Returns the data stored in this decoder as represented in a container
    /// keyed by the given key type.
    ///
    /// - parameter type: The key type to use for the container.
    /// - returns: A keyed decoding container view into this decoder.
    /// - throws: `DecodingError.typeMismatch` if the encountered stored value is
    ///   not a keyed container.
    func container<Key>(keyedBy type: Key.Type) throws -> KeyedDecodingContainer<Key> where Key : CodingKey

    /// Returns the data stored in this decoder as represented in a container
    /// appropriate for holding values with no keys.
    ///
    /// - returns: An unkeyed container view into this decoder.
    /// - throws: `DecodingError.typeMismatch` if the encountered stored value is
    ///   not an unkeyed container.
    func unkeyedContainer() throws -> UnkeyedDecodingContainer

    /// Returns the data stored in this decoder as represented in a container
    /// appropriate for holding a single primitive value.
    ///
    /// - returns: A single value container view into this decoder.
    /// - throws: `DecodingError.typeMismatch` if the encountered stored value is
    ///   not a single value container.
    func singleValueContainer() throws -> SingleValueDecodingContainer

singleValueContainer(这是一个错误,答案澄清了 - 谢谢!)和 unkeyedContainer 抛出数组,并显示一条消息,表明它们不支持数组。我可以使用container(keyedBy:),我应该传递什么作为密钥?

【问题讨论】:

    标签: json swift decodable


    【解决方案1】:

    我认为这不是一个好方法,因为[Tubby].self 足够简单,可以在任何地方使用。 但是如果你只是想将数组包装在另一种类型中,你应该有这样的东西:

    详细版本:

    struct Tubbies: Codable {
        let tubbies: [Tubby]
        
        init(from decoder: Decoder) throws {
            let container = try decoder.singleValueContainer()
            self.tubbies = try container.decode([Tubby].self)
        }
    }
    

    短版:

    struct Tubbies: Codable {
        let tubbies: [Tubby]
        
        init(from decoder: Decoder) throws {
            tubbies = try [Tubby](from: decoder)
        }
    }
    

    用法:

    let tubbies: Tubbies = try! JSONDecoder().decode(Tubbies.self, from: jsonData)
    

    【讨论】:

    • 另一个选项是tubbies = try [Tubby](from: decoder)
    • 太好了,谢谢!我认为我没有正确查看singleValueContainer() - 我以为我已经尝试过了,但它引发了错误!非常感谢。较短的版本非常简洁,并强调 Decodableinit 来自 Decoder 的东西,我喜欢。
    猜你喜欢
    • 1970-01-01
    • 2021-06-08
    • 1970-01-01
    • 1970-01-01
    • 2020-10-24
    • 2021-01-31
    • 2011-06-05
    • 2018-12-04
    • 1970-01-01
    相关资源
    最近更新 更多