Не удается проанализировать данные json в swift

#ios #json #swift #api #nsdictionary

#iOS #json #swift #API #nsdictionary

Вопрос:

У меня есть ответ API, приведенный ниже:

 {
    "status": 200,
    "schedule_data": {
        "2020_08_16_1597485600": {
            "schedule_date": "2020-08-16",
            "nanny_id": 2,
            "shift_start": "06:00",
            "shift_end": "13:00",
            "schedule_id": 112
        },
        "2020_08_16": {
            "schedule_date": "2020-08-16",
            "nanny_id": 2,
            "shift_start": "",
            "shift_end": "",
            "schedule_id": 0
        },
        "2020_08_17_1597485600": {
            "schedule_date": "2020-08-17",
            "nanny_id": 2,
            "shift_start": "06:00",
            "shift_end": "22:00",
            "schedule_id": 113
        },
        "2020_08_17": {
            "schedule_date": "2020-08-17",
            "nanny_id": 2,
            "shift_start": "",
            "shift_end": "",
            "schedule_id": 0
        },
        "2020_08_18": {
            "schedule_date": "2020-08-18",
            "nanny_id": 2,
            "shift_start": "",
            "shift_end": "",
            "schedule_id": 0
        },
        "2020_08_19": {
            "schedule_date": "2020-08-19",
            "nanny_id": 2,
            "shift_start": "",
            "shift_end": "",
            "schedule_id": 0
        },
        "2020_08_20": {
            "schedule_date": "2020-08-20",
            "nanny_id": 2,
            "shift_start": "",
            "shift_end": "",
            "schedule_id": 0
        },
        "2020_08_21": {
            "schedule_date": "2020-08-21",
            "nanny_id": 2,
            "shift_start": "",
            "shift_end": "",
            "schedule_id": 0
        },
        "2020_08_22": {
            "schedule_date": "2020-08-22",
            "nanny_id": 2,
            "shift_start": "",
            "shift_end": "",
            "schedule_id": 0
        },
        "2020_08_23": {
            "schedule_date": "2020-08-23",
            "nanny_id": 2,
            "shift_start": "",
            "shift_end": "",
            "schedule_id": 0
        },
        "2020_08_24": {
            "schedule_date": "2020-08-24",
            "nanny_id": 2,
            "shift_start": "",
            "shift_end": "",
            "schedule_id": 0
        },
        "2020_08_25": {
            "schedule_date": "2020-08-25",
            "nanny_id": 2,
            "shift_start": "",
            "shift_end": "",
            "schedule_id": 0
        },
        "2020_08_26": {
            "schedule_date": "2020-08-26",
            "nanny_id": 2,
            "shift_start": "",
            "shift_end": "",
            "schedule_id": 0
        },
        "2020_08_27": {
            "schedule_date": "2020-08-27",
            "nanny_id": 2,
            "shift_start": "",
            "shift_end": "",
            "schedule_id": 0
        },
        "2020_08_28": {
            "schedule_date": "2020-08-28",
            "nanny_id": 2,
            "shift_start": "",
            "shift_end": "",
            "schedule_id": 0
        },
        "2020_08_29": {
            "schedule_date": "2020-08-29",
            "nanny_id": 2,
            "shift_start": "",
            "shift_end": "",
            "schedule_id": 0
        },
        "2020_08_30": {
            "schedule_date": "2020-08-30",
            "nanny_id": 2,
            "shift_start": "",
            "shift_end": "",
            "schedule_id": 0
        },
        "2020_08_31": {
            "schedule_date": "2020-08-31",
            "nanny_id": 2,
            "shift_start": "",
            "shift_end": "",
            "schedule_id": 0
        }
    }
}
  

У меня есть модель данных для этого ответа API, и она выглядит следующим образом:

 import Foundation

struct Welcome: Codable {
    let status: Int
    let scheduleData: [String: ScheduleDatum]

    enum CodingKeys: String, CodingKey {
        case status
        case scheduleData = "schedule_data"
    }
}

// MARK: - ScheduleDatum
struct ScheduleDatum: Codable {
    let scheduleDate: String?
    let nannyID: Int?
    let shiftStart: String?
    let shiftEnd: String?
    let scheduleID: Int?

    enum CodingKeys: String, CodingKey {
        case scheduleDate = "schedule_date"
        case nannyID = "nanny_id"
        case shiftStart = "shift_start"
        case shiftEnd = "shift_end"
        case scheduleID = "schedule_id"
    }
}
  

Я хочу значения schedule_date для данных, где schedule_id не равен нулю.Эти schedule_data представляют собой массив словаря.Синтаксический анализ json выполняется таким образом в коде ios swift.

 let decoder = JSONDecoder()
      
      do {
          
          let user = try decoder.decode(ScheduleListModel.self, from: response.data!)
          self.listdata = user
       

       
        if (self.listdata?.scheduleData.count)! > 0
       {

       }
       else
       {
        self.showAlert(message: "No schedule available")
       }
       
         } catch {
             debugPrint(error)
      }
  

Как извлечь значения внутри словаря этого массива?

Комментарии:

1. Что такое ScheduleListModel ? Вы должны расшифровать Welcome .

Ответ №1:

Здесь есть несколько вещей, которые необходимо улучшить. Во-первых, свойства модели не обязательно должны быть необязательными, если ключи никогда не станут nil . Во-вторых, ключи кодирования не требуются, поскольку то же самое может быть достигнуто с помощью convertFromSnakeCase .

Модель:

 let data = Data(string.utf8)

struct Welcome: Codable {
    let status: Int
    let scheduleData: [String: ScheduleDatum]
}

struct ScheduleDatum: Codable {
    let scheduleDate: String
    let nannyId: Int
    let shiftStart: String
    let shiftEnd: String
    let scheduleId: Int
}
  

Необходимо выполнить декодирование для модели Welcome . Кроме того, выполните цикл по данным, чтобы получить scheduleDates . Вот как:

 do {
    let decoder = JSONDecoder()
    decoder.keyDecodingStrategy = .convertFromSnakeCase

    let user = try decoder.decode(Welcome.self, from: response.data)
    var scheduleDates = [String]()

    for schedule in user.scheduleData {
        if schedule.value.scheduleId != 0 {
            scheduleDates.append(schedule.value.scheduleDate)
        }
    }
    print(scheduleDates)
} catch {
    debugPrint(error)
}
  

Ответ №2:

Вы можете фильтровать словарь на основе его значений и извлекать даты. Вы должны использовать Welcome model для анализа JSON и выполнения фильтрации.

Вот код :

 let decoder = JSONDecoder.init()

let welcomeModel = try! decoder.decode(Welcome.self, from: response.data)

welcomeModel.scheduleData.enumerated().forEach {
    if $1.value.scheduleID != 0 || $1.value.scheduleID != nil {
        print($1.value.scheduleDate ?? "Date is nil")
    } 
}