0

I have the json

{
  "message": null,
  "data": {
    "Commodity Department": {
      "total": 2,
      "completed": 1,
      "completedWithDue": 0,
      "completedWithOutDue": 1,
      "inProgress": 1,
      "inProgressWithDue": 0,
      "inProgressWithOutDue": 1,
      "statusCounter": null
    }
}

I need to convert the each department json object to array. Currently each category value ("total": 0, "completed": 0, "completedWithDue": 0, "completedWithOutDue": 0, "inProgress": 0, "inProgressWithDue": 0, "inProgressWithOutDue": 0,) will be in object format. I need to convert in array and load to collectionview based on category. As of now I am trying to decode my json in the below code

public struct Dashboard: Decodable {
    public let data : [String:Departments]
}

public struct Departments: Decodable {
    public let total, completed, completedWithDue, completedWithOutDue: Int
    public let inProgress, inProgressWithDue, inProgressWithOutDue: Int
}

let dashboard = try? JSONDecoder().decode(Dashboard.self, from: response.data!)

print(dashboard!.data.keys)
Ben10
  • 3,221
  • 2
  • 34
  • 61
  • 1
    What is the question? – vadian Dec 20 '19 at 12:34
  • @vadian currently each category value ("total": 0, "completed": 0, "completedWithDue": 0, "completedWithOutDue": 0, "inProgress": 0, "inProgressWithDue": 0, "inProgressWithOutDue": 0,) will be in object format. i need to convert array load to collectionview based on category – Ben10 Dec 20 '19 at 12:36
  • For readability, please add code to your question instead of in the comments. Also, what is the output of `print(dashboard!.data.keys)` ? – koen Dec 20 '19 at 12:41
  • Does this answer your question? [How to parse Array of JSON to array in Swift](https://stackoverflow.com/questions/42081141/how-to-parse-array-of-json-to-array-in-swift) – koen Dec 20 '19 at 12:43
  • @koen I get the deparment names All Departments,Portfolio Mangement Service..... – Ben10 Dec 20 '19 at 12:44
  • How about using the (sorted) keys as data source? By the way I have a deja-vue: It seems that you asked a similar question a few hours ago. Please see (again) this answer: https://stackoverflow.com/questions/54129682/use-swift-codable-to-decode-json-with-values-as-keys/54131007#54131007 – vadian Dec 20 '19 at 12:45
  • Use like this- print(Array(dashboard!.data.keys)) and print(((dashboard!.data.values))) – Pramod Shukla Dec 20 '19 at 12:53
  • what is your question? I run this code and it works just fine – rolling_codes Dec 20 '19 at 13:01
  • @NoodleOfDeath currently each category value ("total": 0, "completed": 0, "completedWithDue": 0, "completedWithOutDue": 0, "inProgress": 0, "inProgressWithDue": 0, "inProgressWithOutDue": 0,) will be in object format. i need to convert array load to collectionview based on category – Ben10 Dec 20 '19 at 13:03
  • Please update your question to include that information. Chances are you will just need to do an array map transformation – rolling_codes Dec 20 '19 at 13:04

2 Answers2

0

You can decode json without knowing keys like this:

func printJSON(json: [String:Any]) {
let jsonKeys = json.keys //Gets the list of keys on the outer-most layer of the JSON
for i in 0..<jsonKeys.count {
    let level1 = json[jsonKeys.index(jsonKeys.startIndex, offsetBy: i)] //retrieves the object with the specific keys
    if let level2 = json[level1.key] as? [String:Any]{ //if the key is another object
        printJSON(json: level2) //send it as a new json object to the function again
    } else if let level2 = json[level1.key] as? [[String:Any]] { //if the key is an array of objects
        for i in 0..<level2.count { //loop through the array
            printJSON(json: level2[i]) //send each array element to the function
        }
    } else if let value = json[level1.key] as? String { //if value of String/Integer/Bool type
        print(value) //then only print values of the specified type (String-type in this case)
    }
}

}

See full article Here

Zain
  • 153
  • 9
0

You can create an array of the values by adding a computed property to your struct

public struct Departments: Decodable {
    public let total, completed, completedWithDue, completedWithOutDue: Int
    public let inProgress, inProgressWithDue, inProgressWithOutDue: Int

    var categoryValues: [Int] {get {
        return [total, completed, completedWithDue, completedWithOutDue,
         inProgress, inProgressWithDue, inProgressWithOutDue]
        }
    }
}

or create the array on the fly using map

dashboard?.data.mapValues{[$0.total, $0.completed, $0.completedWithDue, ...]}
Joakim Danielson
  • 43,251
  • 5
  • 22
  • 52