Guillaume Mnt
Guillaume Mnt

Reputation: 35

Swift : How to create a dictionary dynamically from a json?

I'd like some advice from you. I would like to create a dictionary from a dynamic response fetch from an API and send that dictionary in an Alamofire POST request.

From what I have so far it's working but I'm not satisfied with what i've made and I think the code is really messy.

Here is an example of what I can receive

"content": {
    "type": "form",
    "fields": [
        {
            "type": "select",
            "label": "Do you have your documents?",
            "field": "user.has_docs",
            "default": 0,
            "choices": [
                {
                    "value": 0,
                    "name": "Not yet"
                },
                {
                    "value": 1,
                    "name": "I do"
                }
            ]
        },
        {
            "type": "input",
            "field": "user.date",
            "label": "When do you arrive?",
        }
   ]
}

After parsing the json with the Codable protocol, I have all my data in the Model Field

Choice

So I want to create my dictionary and I want the following scheme :

{
  "value": {
    "user": {
      "has_docs": 1,
      "date": "29/07/2020"
    }
  }
}

The key named : "value" is always the same value, but the other one depends of the result from the API. the prefix of the field corresponding of "parent object" and the right part is the child.

Hard coding a dictionary in Swift is not that hard, I would do

let dict = [
    "value": [
        "user": [
            "has_docs": 1,
            "date": "29/07/2020"
        ]
    ]
]

But the troubles begin, at the attempt of creating a dictionary dynamically. Values inside user keep only the last one and replacing has_docs with date.

I have found a workaround with using flatmap and reduce but it only allows the type [String: String], unfortunately I need to write [String: Int] too in the dictionary.

here is a sample of the code

let flattenedDictionary = [key : dictionaries
   .flatMap { $0 }
   .reduce([String:String]()) { (dict, tuple) in
       var nextDict = dict
       nextDict.updateValue(tuple.1 as! String, forKey: tuple.0)
       return nextDict
   }]
parameters["value"] = flattenedDictionary

Here : key = "user". dictionaries = [["has_docs": 1], ["date": "29/07/2020"]]

Feel free to exchange if you need more informations

If you have any clue on how you could helping me, I'll highly appreciate, thanks for reading so far.

I hope I was very understandable.

Edit

From a general view : I'd like to create a dictionary dynamically [String: [String: [String: Any]]]

Upvotes: 0

Views: 1296

Answers (1)

New Dev
New Dev

Reputation: 49590

A bit unclear if you have a [String: [String: [String: Any]]] or [String: [String: Any]] dictionary, but the concept of creating it dynamically would be rather similar.

var user: [String: Any] = [:]
user["has_docs"] = 1
user["date"] = Date()

let dict = ["value": user]

Upvotes: 1

Related Questions