Home > Net >  How to skip the value of UnkeyedDecodingContainer while decoding?
How to skip the value of UnkeyedDecodingContainer while decoding?

Time:01-05

I need to decode a JSON with my custom implementation

internal init(from decoder: Decoder) throws {
        var container: UnkeyedDecodingContainer = try decoder.unkeyedContainer()

        while !container.isAtEnd {
            if let obj = try? container.decode(Node.self) {
                parserableArr.append(obj)
            }
            else if let obj = try? container.decode(NodeGPU.self) {
                parserableArr.append(obj)
            }
        }
    }

So, the flow is - I get container and try to decode it with each type one by one. The problem is that if I didn't find the needed type I was stuck in an infinity loop, because the while !container.isAtEnd is never stopped.

I am looking for a method like container.skipValue(), so I can use it like this

...
else {
  container.skipValue()
}
...

But there is no such method.

P.S. Of course I can use a kind of workaround and provide kind of the dummy implementation in the last else state which won't throw, but I am wondering if there is a way to make it work without such a workaround?

CodePudding user response:

This question was already discussed here: Swift JSONDecode decoding arrays fails if single element decoding fails

You can catch an error and decode a "DummyCodable" like that

catch let error {
    _ = try? itemContainer.decode(DummyCodable.self)
}

DummyCodable looks like:

public struct DummyCodable: Codable {}

CodePudding user response:

Eventually, I went with this solution - https://forums.swift.org/t/pitch-unkeyeddecodingcontainer-movenext-to-skip-items-in-deserialization/22151/17 (thanks to @Larme)

struct Empty: Decodable { }

extension UnkeyedDecodingContainer {
  public mutating func skip() throws {
    _ = try decode(Empty.self)
  }
}
  •  Tags:  
  • Related