Home > Software design >  Swift make init Dictionary in struct
Swift make init Dictionary in struct

Time:10-31

i have a let of [[String:Any]] that i want to put it inside my struct data model, because i want to edit the data, can anyone tell me how should i make the dictionary that can contain this type of dictionary?

this is the var dictionary :

let toolListDict : [[String:Any]] = [
    [
        "Name": "Wrench",
        "qty": 6
    ],
    [
        "Name": "Cutter",
        "qty": 15
    ],
    [
        "Name": "Pliers",
        "qty": 12
    ],
    [
        "Name": "ScrewDriver",
        "qty": 13
    ],
    [
        "Name": "Welding Machine",
        "qty": 3
    ],
    [
        "Name": "Welding Glasses",
        "qty": 7
    ],
    [
        "Name": "Hammer",
        "qty": 4
    ],
    [
        "Name": "Measuring Tape",
        "qty": 9
    ],
    [
        "Name": "Alan Keyset",
        "qty": 4
    ],
    [
        "Name": "Air Compressor",
        "qty": 2
    ]
]

and so far this is the model data that i created :

struct Tools: Codable{
var name: String
var qty : Int

init(name: String, qty: Int){
    self.name = name
    self.qty = qty
}

}

how do i make an init dictionary inside my struct so i can just put that let into my struct?

i want to just add that dict into my data model like this :

let tool = try Tools(dict: toolListDict)

i hope i explain it clearly enough sorry if my english kinda confusing, thanks.

CodePudding user response:

Here are two possible solutions. First one is to map from the dictionary elements into the struct. For this we need a failable initializer since we are using compactMap

Note that I took the liberty to change the naming somewhat of the custom type

struct Tool: Codable {
    var name: String
    var quantity : Int

    init?(name: String?, quantity: Int?) {
        guard let name = name, let quantity = quantity else {
            return nil
        }
        self.name = name
        self.quantity = quantity
    }

    //...
}

Then it becomes simple to convert toolListDict

let tools = toolListDict.compactMap { 
    Tool(name: $0["Name"] as? String, quantity: $0["qty"] as? Int) 
}

Another option is to first encode the dictionary using JSONSerialization and then decode the result using JSONDecoder, for this we need to add a CodingKey enum to the custom type

enum CodingKeys: String, CodingKey {
    case name = "Name"
    case quantity = "qty"
}

and the encoding/decoding is done like this

do {
    let data = try JSONSerialization.data(withJSONObject: toolListDict)
    let tools = try JSONDecoder().decode([Tool].self, from: data)
    //...
} catch {
    print(error)
}
  • Related