There are several errors in the code, but you are on the right track. You use the wrong key when initializing your users, city and city structures. I also created two more initializers so that you can initialize your structure with a dictionary, json string, or just your data:
struct Contact: CustomStringConvertible { let user: User let address: Address let deliveryInstruction: String let deliveryMethod: String // customize the description to your needs var description: String { return "\(user.name) \(deliveryInstruction) \(deliveryMethod)" } init(dictionary: [String: Any]) { self.deliveryInstruction = dictionary["delivery_instruction"] as? String ?? "" self.deliveryMethod = dictionary["delivery_method"] as? String ?? "" self.address = Address(dictionary: dictionary["address"] as? [String: Any] ?? [:]) self.user = User(dictionary: dictionary["user"] as? [String: Any] ?? [:]) } init?(data: Data) { guard let json = (try? JSONSerialization.jsonObject(with: data)) as? [String: Any] else { return nil } self.init(dictionary: json) } init?(json: String) { self.init(data: Data(json.utf8)) } }
struct User: CustomStringConvertible { let name: String let email: String let phone: String let description: String init(dictionary: [String: Any]) { self.name = dictionary["name"] as? String ?? "" self.email = dictionary["email"] as? String ?? "" self.phone = dictionary["phoneNo"] as? String ?? "" self.description = "name: \(name) - email: \(email) - phone: \(phone)" } }
struct Address: CustomStringConvertible { let id: String let street: String let house: String let city: City let town: Town let description: String init(dictionary: [String: Any] ) { self.id = dictionary["address_id"] as? String ?? "" self.description = dictionary["full_address"] as? String ?? "" self.house = dictionary["house"] as? String ?? "" self.street = dictionary["street"] as? String ?? "" self.city = City(dictionary: dictionary["city"] as? [String: Any] ?? [:]) self.town = Town(dictionary: dictionary["town"] as? [String: Any] ?? [:]) } }
struct City: CustomStringConvertible { let id: String let name: String // customize the description to your needs var description: String { return name } init(dictionary: [String: Any] ) { self.id = dictionary["city_id"] as? String ?? "" self.name = dictionary["city_name"] as? String ?? "" } }
struct Town: CustomStringConvertible { let id: String let name: String // customize the description to your needs var description: String { return name } init(dictionary: [String: Any]) { self.id = dictionary["town_id"] as? String ?? "" self.name = dictionary["town_name"] as? String ?? "" } }
Check initialization from JSON:
let json = "{\"user\": {\"name\": \"crst\",\"email\": \" crat@gmail.com \",\"phoneNo\":\"018833455\"},\"address\": {\"house\": \"100\",\"street\": \"B\",\"town\":{\"town_id\": \"1\",\"town_name\": \"Galway city center\"},\"city\":{\"city_id\": \"10\",\"city_name\": \"Galway\"},\"address_id\":\"200\", \"full_address\":\"100, B, Galway city center,Galway\" },\"delivery_instruction\": \"no call\",\"delivery_method\": \"1\" }" let contact = Contact(json: json) // crst no call 1 contact // crst no call 1 contact?.user // name: crst - email: crat@gmail.com - phone: 018833455 contact?.user.name // "crst" contact?.user.email // " crat@gmail.com " contact?.user.phone // "018833455" contact?.address // 100, B, Galway city center,Galway contact?.address.id // 200 contact?.address.street // B contact?.address.town // Galway city center contact?.address.city // Galway contact?.deliveryInstruction // "no call" contact?.deliveryMethod // 1