Home > Enterprise >  How to make JSON from nested struct
How to make JSON from nested struct

Time:05-31

I have a nested struct:

struct Order: Codable {
    
    let foodList: [FoodList]
    let name: String
    let phone: String
    let email: String
}

struct FoodList: Codable {
    
    let foodName: String
    let foodID: String
    let foodAmount: Int
}

I need to make JSON from this struct. It have to be like this:

{
  "name": "Name",
  "phone": " 1 999 999 999 999",
  "email": "[email protected]",
  "foodList": [
    {
      "foodName": "Big Mac",
      "foodID": "115",
      "foodAmount": 2
    },
    {
      "foodName": "Naggets",
      "foodID": "221",
      "foodAmount": 5
    }
  ]
}

But I always get this JSON )

[
  {
    "email": "Name",
    "phone": " 1 999 999 999 999",
    "foodList": {
      "foodAmount": 2,
      "foodID": "115",
      "foodName": "Big Mac"
    },
    "name": "[email protected]"
  },
  {
    "email": "[email protected]",
    "phone": " 1 999 999 999 999",
    "foodList": {
      "foodAmount": 5,
      "foodID": "221",
      "foodName": "Naggets"
    },
    "name": "Name"
  }
]

In JSON it have to be 1 Person and array of selected food.

I code JSON to struct with this code:

let orderList = [OrderList]()
for index in 0..<subMenuList.count {
    if subMenuList[index].foodList.foodSelectedAmount != 0 {
        
        orderList.append(OrderList(
                            foodList: FoodListOrder(
                                foodName: subMenuList[index].foodList.foodName,
                                foodID: subMenuList[index].foodList.foodID,
                                foodAmount: subMenuList[index].foodList.foodSelectedAmount),
                            name: mainView.nameTextField.text!,
                            phone: mainView.phoneTextField.text!,
                            email: mainView.emailTextField.text!))
    }
let jsonEncoder = JSONEncoder()
do {
    let jsonData = try jsonEncoder.encode(orderList)
    print(String(data: jsonData, encoding: .utf8)!)
} catch {
    print(error)
}

Something wrong in "FOR" block and textfields... I think. I am appending person's data from textfields each time it loops.

CodePudding user response:

Assuming Order is equal to OrderList and FoodList is equal to FoodListOrder you have to create first the FoodList array and then create the (single) Order object.

var foodList = [FoodList]()
for item in subMenuList { // don't use an index based loop if you actually don't need the index
    if item.foodList.foodSelectedAmount != 0 {
        foodList.append(FoodList(foodName: item.foodList.foodName,
                                 foodID: item.foodList.foodID,
                                 foodAmount: item.foodList.foodSelectedAmount)
    }
}
let order = Order(foodList: foodList,
                  name: mainView.nameTextField.text!,
                  phone: mainView.phoneTextField.text!,
                  email: mainView.emailTextField.text!)

let jsonEncoder = JSONEncoder()
do {
    let jsonData = try jsonEncoder.encode(order)
    print(String(data: jsonData, encoding: .utf8)!)
} catch {
    print(error)
}
  • Related