Saranya
Saranya

Reputation: 675

Unable to parse a JSON data in swift

I have a API response as given below:

{
    "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
        }
    }
}

I have the data model for this API response and it is as follows:

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"
    }
}

I want the schedule_date values for the data where the schedule_id is not zero. This schedule_data is an array of dictionary. The JSON parsing is done this way in the iOS swift code:

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)
      }

How to fetch the values inside the dictionary of this array?

Upvotes: 0

Views: 1552

Answers (2)

Frankenstein
Frankenstein

Reputation: 16361

There are a few things to be improved here. First, the model properties don't have to be optional if the keys never become nil. Secondly, the coding keys are not required as the same can be achieved by convertFromSnakeCase.

Model:

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
}

Decoding needs to be done to the model Welcome. Also, loop through the data to get the scheduleDates. Here's how:

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)
}

Upvotes: 1

Serhat
Serhat

Reputation: 76

You can filter dictionary based on its values and fetch the dates. You should use Welcome model to parse the JSON and do the filtering.

Here is the code :

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")
    } 
}

Upvotes: 0

Related Questions