1

I am passing a bunch of objects from a JSON but it turns out some of them have an empty string instead of a URL. My model expects a valid URL and I would rather skip the non-conforming objects than make the URL property optional.

This turns out to not be that straight-forward. Is there a built-in way to skip non-decodable objects from an array?

1
  • That's weird then that my search this time didn't turn it up. Commented Sep 5, 2018 at 9:24

1 Answer 1

3

It turns out that this is an open problem with a ticket in Swift.

I implemented the workaround as posted there on my problem in the following way:

struct AnyCodable: Codable {}

struct Trending: Codable {
  var data: [Gif]

  init(from decoder: Decoder) throws {
    let container = try decoder.container(keyedBy: CodingKeys.self)

    var gifContainer = try container.nestedUnkeyedContainer(forKey: .data)

    var gifs = [Gif]()

    while !gifContainer.isAtEnd {
      if let gif = try? gifContainer.decode(Gif.self) {
        gifs.append(gif)
      } else {
        let skipped = try? gifContainer.decode(AnyCodable.self)
        print("Skipping one \(skipped)")
      }
    }

    self.data = gifs
  }
}
Sign up to request clarification or add additional context in comments.

2 Comments

Came here to validate my own solution and found this. I can see it's been answered elsewhere, but this more succinctly answers the question. The only differences I had were this: struct AnyDecodable: Decodable {} and _ = try gifContainer.decode(AnyCodable.self) You want to remove the try? because you might find yourself in an infinite loop.
You want to remove the try? for the line with let skipped? I want a handle on it to be able to print it out, so it might be better to remove the try? and turn the entire thing into another if let?

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.