0

I tried a lot of different methods but none really helps. I need to read in data that has a set of expected keys and a range of unknown keys. All must be read in. For example the json is like this;

{
  "name": "",
  "age": null,
  "street": "",
  "appended/1": null,
  "appended/2": null,
  "appended/3": null
}

The struct and coding keys for name, age and street is obvious. But how do I get to the 'appended/1' , 'appended/2' etc ? this list can be quite long and I would like to programmatically fetch the data.

I have tried ;

init(from decoder: Decoder) throws {

   let container = try decoder.container(keyedBy: CodingKeys.self)
   id = try container.decode(Int.self, forKey: .id)
   name = try container.decodeIfPresent(String.self, forKey: .name) ?? ""
   etc.
}

The above will only fetch the name and other codingkeys that are defined, and obviously works as expected. If have tried to work with dynamic coding keys like so ;

init(from decoder: Decoder) throws {

   let dynamicKeysContainer = try decoder.container(keyedBy: DynamicCodingKey.self)
         
   var appended: [Appended] = []
   try dynamicKeysContainer.allKeys.forEach { key in
   if key.stringValue.starts(with: "appended/"), let appendedNumber = Int(key.stringValue.split(separator: "/")[1]) {

   appendedFound.append = try dynamicKeysContainer.decode([Appended].self, forKey: key)

   }
}

   let container = try decoder.container(keyedBy: CodingKeys.self)
   id = try container.decode(Int.self, forKey: .id)
   name = try container.decodeIfPresent(String.self, forKey: .name) ?? ""
   appended = appendedFound
}

however doing this, will put the 'cursor' of the decoder at the end of the file when it is done decoding the dynamic keys. And I cannot fetch my data using my regular coding keys.

How can this be done?

jnpdx
  • 45,847
  • 6
  • 64
  • 94
  • 1
    What do you mean by "cursor" here? There is no "cursor" in a keyed decoding container. Decoding containers are views. They do not consume data. You absolutely can decode all your dynamic keys first and then regular keys second. Have you tried this and had a problem? Note that AI-generated answers currently banned on SO. https://meta.stackoverflow.com/questions/421831/temporary-policy-chatgpt-is-banned?cb=1 – Rob Napier Mar 13 '23 at 02:37
  • Have you read my problem ? if so , you would have seen that I have tried exactly what you propose. Finally, I had no idea abt ai being banned on SO. I will delete my answer, even tho its the answer I was looking for and perhaps others. – Learn2Code Mar 13 '23 at 06:22
  • The problem with your above code isn't related to a cursor. The AI-generated code you posted looked probably correct (it's tricky to code-review AI-generated code; they often write code that looks correct but has subtle bugs that aren't the kind of mistakes humans make, so they're harder to recognize). If you play with the AI-generated code, you'll find that you can decode the containers in either order. It has nothing to do with a cursor. So while the answer is likely correct, it's confusing to searchers because it suggests a problem that doesn't exist. – Rob Napier Mar 13 '23 at 12:52
  • Here is another approach to the problem: https://stackoverflow.com/questions/50116897/is-it-possible-to-decode-additional-parameters-using-jsondecoder/50117723#50117723 for a longer discussion of what you're trying to do, see https://youtu.be/-k_vipGhugQ?t=627 starting around 10:30. – Rob Napier Mar 13 '23 at 13:03
  • Or you could use `JSONSerialization` for this – Joakim Danielson Mar 13 '23 at 21:39

0 Answers0