Ordering info of Dictionary to populate a tableView

delbertoms91 Source

I'm dealing with this. This is mi JSON response

{
    "code": 200,
    "message": "ok",
    "data": {
        "section1": [
            {
                "clave": "xxxx",
                "orden": 0,
                "nombre": "xxxxx",
                "video": "xxxxx",
                "imagen": "xxxxx",
                "series": 0,
                "repeticiones": 0,
                "descanso":0,
                "completado": false
            },
            {
                "clave": "xxxx",
                "orden": 0,
                "nombre": "xxxxx",
                "video": "xxxxx",
                "imagen": "xxxxx",
                "series": 0,
                "repeticiones": 0,
                "descanso":0,
                "completado": false
            }
          }
        ],
        "section2": [
            {
                "clave": "xxx",
                "equipo": "xx",
                "imagen": "x",
                "tiempo": 0,
                "intensidad": 0,
                "completado": false
            }
        ],
        "section3": [
            {
                "clave": "xxx",
                "nombre": "xxxx",
                "imagen": "",
                "completado": false
            },
            {
                "clave": "xxx",
                "nombre": "xxxx",
                "imagen": "",
                "completado": false
            }


        ],
        "section4": [
            {
                "clave": "xx",
                "nombre": "xxxx",
                "imagen": "x",
                "completado": false
            },
            {
                 "clave": "xx",
                "nombre": "xxxx",
                "imagen": "x",
                "completado": false
            }
        ]
    }
}

What I want to do is display the info in sections, the sections should be "section1", "section2", "section3", "section4" ,obviously and display all the info that "section1" contains, and if the section is "section2" display all the info in cardios an so on... But I want to display it in the same tableView just divided in sections Could you help me?. thanks in Advance

iosswiftuitableviewnsdictionary

Answers

answered 1 month ago bseh #1

Since NSDictionary is not an ordered data container, you would have to use a different data structure or you would have to update the API and return an ordered array inside the "data".

answered 1 month ago Antoine Rucquoy #2

Another solution should create a custom parser which will convert your data into an array of a model which would represent any section.

Model

class SomethingObj {
    var clave: String?
    var orden: Int?
    var nombre: String?
    var video: String?
    var imagen: String?
    var series: Int?
    var repeticiones: Int?
    var descanso: Int?
    var completado: Bool?

    init() {
    }
}

Parser

private func parseData(for structure: NSDictionary) -> [[SomethingObj]] {
    var sectionsArray = [[SomethingObj]]()

    guard let sectionsLoop = structure["data"] as? NSDictionary else { return sectionsArray }

    var sectionIndex = 1

    while let sectionObjsData = sectionsLoop["section\(sectionIndex)"] as? [NSDictionary] {
        var sectionArray = [SomethingObj]()

        for sectionObjData in sectionObjsData {
            let obj = SomethingObj()

            obj.clave = sectionObjData["clave"] as? String
            obj.orden = sectionObjData["orden"] as? Int
            obj.nombre = sectionObjData["nombre"] as? String
            obj.video = sectionObjData["video"] as? String
            obj.imagen = sectionObjData["imagen"] as? String
            obj.series = sectionObjData["series"] as? Int
            obj.repeticiones = sectionObjData["repeticiones"] as? Int
            obj.descanso = sectionObjData["descanso"] as? Int
            obj.completado = sectionObjData["completado"] as? Bool

            sectionArray.append(obj)
        }

        sectionsArray.append(sectionArray)

        sectionIndex = sectionIndex + 1
    }

    return sectionsArray
}

Display parsed data

Use whatever you want in order to display something with your array of parsed data.

answered 1 month ago vadian #3

First of all in the JSON above Section2 is a extraneous closing brace.

This is a starting point.

Decode the value for data as [String:[Item]] and map each dictionary to a helper struct Section containing the name (dictionary key) and the array of Item (dictionary value). The sections array is sorted by name

struct Root : Decodable {
    let code : Int
    let message : String
    let sections : [Section]

    enum  CodingKeys: String, CodingKey { case code, message, sections = "data"}

    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        code = try container.decode(Int.self, forKey: .code)
        message = try container.decode(String.self, forKey: .message)
        let data = try container.decode([String : [Item]].self, forKey: .sections)
        sections = data.map({Section(name: $0.0, items: $0.1)}).sorted(by: {$0.name < $1.name})
    }
}

struct Section {
    let name : String
    let items : [Item]
}

struct Item : Decodable {
    let clave : String
    let completado : Bool
    let repeticiones : Int?
    // ... other properties
}

Decode the Root struct (data is the JSON data)

let result = try JSONDecoder().decode(Root.self, from: data)
let sections = result.sections

In the table view sections are the sections and items are the rows

comments powered by Disqus