Разбор ответа JSON в структуру - PullRequest
1 голос
/ 29 мая 2019

Я использую Alamofire и возвращаю данные из API в JSON. Я хочу использовать данные в структуре. ответ следующий:

{
  "status" : 1,
  "data" : [
{
  "classes" : [

  ],
  "day" : "Wednesday"
},
{
  "classes" : [
    {
      "time" : "1:30 PM",
      "available_spots" : 2,
      "trainer" : "Ahmed Jasim",
      "thumbnail" : "\/uploads\/classes\/6\/files\/class_6_15555066955cb72607131886.71740331.jpg",
      "id" : 6,
      "name" : "Gym Class C"
    }
  ],
  "day" : "Thursday"
},
{
  "classes" : [

  ],
  "day" : "Friday"
},
{
  "classes" : [

  ],
  "day" : "Saturday"
},
{
  "classes" : [
    {
      "available_spots" : 2,
      "id" : 1,
      "trainer" : "Ahmed Jasim",
      "name" : "Karate",
      "thumbnail" : "\/uploads\/classes\/1\/files\/class_1_15548800215cad9615e62404.41767774.jpg",
      "time" : "5:00 PM"
    }
  ],
  "day" : "Sunday"
},
{
  "classes" : [
    {
      "thumbnail" : "\/uploads\/classes\/1\/files\/class_1_15548800215cad9615e62404.41767774.jpg",
      "available_spots" : 2,
      "time" : "11:00 AM",
      "name" : "Karate",
      "id" : 1,
      "trainer" : "Ahmed Jasim"
    },
    {
      "trainer" : "Jalal Hassan",
      "available_spots" : 20,
      "thumbnail" : "\/uploads\/classes\/2\/files\/class_2_15548819805cad9dbc7b9a80.11639647.jpg",
      "time" : "4:00 PM",
      "name" : "Gym Class B",
      "id" : 2
    }
  ],
  "day" : "Monday"
},
{
  "classes" : [
    {
      "name" : "Gym Class B",
      "trainer" : "Jalal Hassan",
      "time" : "9:00 AM",
      "available_spots" : 20,
      "id" : 2,
      "thumbnail" : "\/uploads\/classes\/2\/files\/class_2_15548819805cad9dbc7b9a80.11639647.jpg"
    }
  ],
  "day" : "Tuesday"
}
 ],
 "message" : "Retrieved successfully",
 "success" : true
}

Я хочу получить дневные занятия и использовать их в структуре. структура, которую я использую, выглядит следующим образом.

struct section {
day: String!
classes: [String]! 
}

так что я хочу получить день и его уроки и хранить их. вызов для структуры:

 var sections = [Section(day: "Monday", classes: ["A","B","C"]]

что я хочу достичь - это получить все дни и их классы, и если у дня нет классов, это будет просто пустой массив.

но я не уверен, возможно ли это или нет.

это код внутри запроса Alamofire:

     let classesJSON: JSON = JSON(response.result.value!)


                if response.data != nil {

                    for index in 0..<classesJSON["data"].count {

                        var sections = Section(day: classesJSON["data"][index]["day"].stringValue, classes: [])
                        for data in classesJSON["data"].arrayValue {

                            for value in data["classes"].arrayValue {
                                sections.classes.append(value["name"].stringValue)
                               //sections.classes[index] = value["name"].stringValue
                            }
                        }
                        print(sections)
                    }

                }

Моя проблема в том, что я получаю все классы в ответе, я хочу получить определенный класс для дня.

Section(day: Optional("Sunday"), classes: Optional(["Gym Class C", "Karate", "Karate", "Gym Class B", "Gym Class B"])

Section(day: Optional("Monday"), classes: Optional(["Gym Class C", "Karate", "Karate", "Gym Class B", "Gym Class B"])

^ это то, что я получаю, но я хочу разделить их, чтобы я мог провести день и его занятия, не все из них

Ответы [ 2 ]

2 голосов
/ 30 мая 2019

Я бы порекомендовал отказаться от SwiftyJSON и вместо этого использовать объекты реальной модели с Codable.

Разобрать ваши данные, используя такие структуры:

struct APIResponse: Codable {
    let status: Int
    let data: [ClassData]
    let message: String
    let success: Bool
}

struct ClassData: Codable {
    let classes: [Class]
    let day: String
}

struct Class: Codable {
    let time: String
    let availableSpots: Int
    let trainer, thumbnail: String
    let id: Int
    let name: String

    enum CodingKeys: String, CodingKey {
        case time
        case availableSpots = "available_spots"
        case trainer, thumbnail, id, name
    }
}

struct Section {
    let day: String
    let classes: [String]
}

do {
    let response = try JSONDecoder().decode(APIResponse.self, from: json)

    let classesPerDay: [String: [Class]] = response.data.reduce(into: [:]) {
        $0[$1.day, default: []].append(contentsOf: $1.classes)
    }

    let sections = classesPerDay.map { Section(day: $0, classes: $1.map { $0.name }) }
    print(sections)
} catch {
    print(error)
}
0 голосов
/ 30 мая 2019

Вы можете немного изменить свой цикл

for index in 0..<classesJSON["data"].count {
    var classes: [String] = []
    for item in classesJSON["data"][index]["classes"].arrayValue {
          classes.append(item["name"].stringValue)
    }
    let sections = Section(day: classesJSON["data"][index]["day"].stringValue, classes: classes)
    print(sections)
 }

И убедитесь, что вы изменили let на var как для дня, так и для занятий вваша структура

struct Section {
    var day: String
    var classes: [String]
}
...