1

I want to have the following JSON structure (fake example):

{
    "Admin" : 
    {
        "name" : "John",
        "age" : "42"
    },
    "Sales" : 
    {
        "name" : "John",
        "age" : "42"
    },
    "CEO" : 
    {
        "name" : "Peter",
        "age" : "52",
        "salary" : "100000"
    },
    "Janitor" : 
    {
        "name" : "Matthew",
        "age" : "22"
    }
}

As you can see, the structure if determined, but the name of the structure is dynamic.

How can I convert this to a Swift Codable struct? Current try:

struct Positions: Codable
{
    var posDicts: [String: Position] = [:]
}

struct Position: Codable
{
    let name: String
    let age: Int
    let salary: Int?
}

However, this would give the following:

"posDicts" : {
    "Admin" : 
    {
        "name" : "John",
        "age" : "42"
    },
    "Sales" : 
    {
        "name" : "John",
        "age" : "42"
    },
    "CEO" : 
    {
        "name" : "Peter",
        "age" : "52",
        "salary" : "100000"
    },
    "Janitor" : 
    {
        "name" : "Matthew",
        "age" : "22"
    }
}

I don't want the "posDicts" in the JSON. What would be the best/simplest solution?

P.S.: related question regarding decodable Swift Codable with dynamic keys

4
  • This might help: stackoverflow.com/questions/50713638/… Commented Dec 11, 2018 at 17:40
  • @emrepun as you might have noticed, that is the exact same link I provide in my question. (iow: need more than that) Commented Dec 11, 2018 at 17:54
  • Sorry didn't catch that :/ Commented Dec 11, 2018 at 18:00
  • 1
    Can happen, don't worry :D Commented Dec 11, 2018 at 18:04

3 Answers 3

2

Rather than decoding

let result = try JSONDecoder().decode(Positions.self, from: data)

delete the Positions struct and decode

let result = try JSONDecoder().decode([String:Position].self, from: data)

To encode the dictionary accordingly declare it as

 var positions = [String:Position]()
Sign up to request clarification or add additional context in comments.

Comments

0

The answer by Vadian is a good push in the right direction. The solution was to encode the dictionary instead of a struct containing a dictionary.

As the original question is about encoding, the following is a complete solution:

var positions: [String: Position] = [:]
let json = try? encoder.encode(positions)

Comments

0

Encoding with dynamic keys seems like it's not supported at the moment.

I have used dictionary instead of encodable model that requires dynamic keys.

let dict = [dynamicKey: dynamicValue]
class MyModel: Encodable {
      someModelKey: dict
}

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.