-1

I'm getting a JSON that looks like this:

{
    looks =     (
                {
                     ... look object
        }
    );
    query =     (
        ... array of strings
    );
    slices =     (
                (
                        {
                    ... another object
            }
        )
    );

As decoding object I'm using [String: [Look]] because I was expecting just one key (the "looks" one) but unexpectedly received the other two. Of course after decoding correctly the first wrapping key, it fails when trying to decode the "query" one because the content is not [Look]

What's the best approach for this? Ideally I would like an approach flexible enough to handle situations where other top level wrapping keys are added without making the decoding fail in the future.

Thanks!

nandodelauni
  • 291
  • 1
  • 10
  • 1
    What you've written here isn't JSON. Please provide legal JSON you'd like to parse, and what you'd like the resulting structs to look like. – Rob Napier Sep 17 '19 at 17:44

2 Answers2

1

You can use values.decodeIfPresent(Type.self, forKey: .key) in the decoding context

For your case: Create the response class like below:

 struct Result: Decodable {
  var look: [Look]
  var query: [String]?
  var slices: [SlicesType]?

 enum ResultKeys: String, CodingKey {
  case look = "look"
  case query = "query"
  case slices = "slices"
 }

 init(from decoder: Decoder) throws {
  let container = try decoder.container(keyedBy: ResultKeys.self)
  self.look = try container.decodeIfPresent(Look.self, forKey: .look)
  self.query = try container.decodeIfPresent([String].self, forKey: .query)
  self.slices = try container.decodeIfPresent([String].self, forKey: .slices)
 }
}

and while decoding you can use

  let myStruct = try JSONDecoder().decode(Result.self, from: yourJsonData).

It is not mandatory to create the CodingKeys if you have same variable name in struct and key name in json.

This way it will not break the execution if any of the key is missing

Hope this helps!!!

vishnu_146
  • 437
  • 3
  • 14
0

It's difficult to know what you're looking for, because what you've posted isn't JSON, but I assume what you want is this:

struct Looks {
    let looks: [Look]
}

let looks = try JSONDecoder().decode(Looks.self, from: data).looks

Create a simple container that matches the keys you actually receive; then extract the pieces you want from that container.

Rob Napier
  • 286,113
  • 34
  • 456
  • 610