2

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?

Sirop4ik
  • 4,543
  • 2
  • 54
  • 121
  • 1
    There was a discussion and I think a nice workaround: https://forums.swift.org/t/pitch-unkeyeddecodingcontainer-movenext-to-skip-items-in-deserialization/22151/17 but it's still a workaround (it's more or less what you already suggested, just making it in a "method" for the container)., and the MR on the Github hasn't moved since. I wonder if there is still discussion elsewhere... – Larme Jan 03 '22 at 11:17
  • https://bugs.swift.org/plugins/servlet/mobile#issue/SR-5953 – matt Jan 03 '22 at 12:20
  • Duplicate of https://stackoverflow.com/questions/46344963/swift-jsondecode-decoding-arrays-fails-if-single-element-decoding-fails ? – matt Jan 03 '22 at 12:21

2 Answers2

2

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 {}
matt
  • 515,959
  • 87
  • 875
  • 1,141
Patrick_K
  • 219
  • 2
  • 11
1

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)
  }
}
Sirop4ik
  • 4,543
  • 2
  • 54
  • 121