1

I have got json data and I can parse the first part which is nav and name, however I need to parse the array children into a table view.

{
"nav": [
    {
        "name": "Home",
        "navigationName": "Home",
        "icon": null,
        "navigation": {
            "URI": null,
            "type": "CUSTOM",
            "target": "home",
            "depth": null,
            "data": null,
            "filters": {},
            "urlStructure": {
                "title": null,
                "isFeatured": false,
                "isCampaign": false
            }
        },
        "styles": []
    },
    {
        "name": "New In",
        "navigationName": "New In",
        "icon": null,
        "navigation": {
            "URI": null,
            "type": "NO_LINK",
            "target": "",
            "depth": null,
            "data": null,
            "filters": {},
            "urlStructure": {
                "title": null,
                "isFeatured": false,
                "isCampaign": false
            }
        },
        "styles": [
            "linkNewin"
        ],
        "children": [
            {
                "name": "New In Mens",
                "navigationName": "New In Mens",
                "icon": null,
                "navigation": {
                    "URI": "/men?facet:new=latest&sort=latest",
                    "type": "CATEGORY",
                    "target": "men",
                    "depth": null,
                    "data": null,
                    "filters": {
                        "facet:new": "latest",
                        "sort": "latest"
                    },
                    "urlStructure": {
                        "title": null,
                        "isFeatured": false,
                        "isCampaign": false
                    }
                },
                "styles": [
                    "linkNewin"
                ]
            },

That is the json data. I have parsed and populated the first name in the array nav, but cannot do it for the Children array.

I have created this data model so far:

struct Menu: Codable {
    var nav = [Menus]()
}

struct Menus: Codable {
    var name: String
    var children: ChildrensNames
}

struct ChildrensNames: Codable {
    var name: String
}

Does anyone have any ideas?

I have got the structs working so when I add a break point in I can see the children's names, however I do not know how to access these and add them to a second section in. Below is my table view set up

extension MenuViewController: UITableViewDataSource {

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

    if section == 0{
    return self.menu?.nav.count ?? 0
    } else if section == 1 {
        return self.menuItems?.children?.count ?? 0
    } else {
        return 2
    }
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    var cell = tableView.dequeueReusableCell(withIdentifier: "cell")

    if cell == nil {
        cell = UITableViewCell.init(style: .value1, reuseIdentifier: "cell")
    }

    let navItem = self.menu?.nav[indexPath.row].name
    let childItem = self.menu?.nav[indexPath.row].children


    switch indexPath.section {
    case 0:
        cell?.textLabel?.text = navItem
        break
    case 1:
//      cell?.textLabel?.text =

        break
    default:
        break
}


    cell?.accessoryView = UIImageView(image: UIImage(named: "icons8-chevron-right-50"))


    return cell!
}

}

1

3 Answers 3

1

First of all let's rename Menus to avoid confusion. Let's name it NavigationItem.

The value for key children is also an array of NavigationItem and as some dictionaries don't have children make it optional.

If the structs are read-only adopt only Decodable and declare the struct members as constants.

struct Menu: Decodable {
    let nav : [NavigationItem] // Don't declare this struct member as empty array
}

struct NavigationItem : Decodable {
    let name : String
    let navigationName : String
    let children : [NavigationItem]?
}
7
  • ok i have done that, how i would i then get the data from children and populate that in a table view? Commented Nov 18, 2018 at 10:47
  • It depends on the data source structure of the table view. Basically use two for loops to iterate nav and children
    – vadian
    Commented Nov 18, 2018 at 11:24
  • let navItem = self.menu?.nav[indexPath.row].name switch indexPath.section { case 0: cell?.textLabel?.text = navItem break case 1: for _ in navItem! { if self.menu?.nav[indexPath.row].children == nil { return cell! } else { for child in childItems! { cell?.textLabel?.text = } Commented Nov 18, 2018 at 11:27
  • that is what i have to populate the table at the moment, i can populate the nav name but not the child name Commented Nov 18, 2018 at 11:29
  • Please edit your question, add the code and a description about the expected sections and rows of the table view.
    – vadian
    Commented Nov 18, 2018 at 11:43
0

In the JSON data “children” is an array,so you could try this:

struct Menus: Codable {
    var name: String
    var children: [ChildrensNames]  
}

Best Wishes!

0

Try this solution - in order to decode properly you need to define the data provider successfully :

struct Nav: Decodable {
 let nav: [NavItem]
}

struct NavItem: Decodable {
  var name : String?
  var navigationName : String?
  var children: [ChildrenArr]
  //And so on
}

then you can scode it like this:

do {
     let nav = try JSONDecoder().decode(Nav.self, from: data)
     //Do somthing
    } catch let error{
        print(error)
    }

so the tableview should look like this:

func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
    let sectionHeaderCell = tableView.dequeueReusableCell(withIdentifier: "Section") as! SectionTableViewCell

    sectionHeaderCell.name.text = nav?.nav[section].name

    return sectionHeaderCell
}

func numberOfSections(in tableView: UITableView) -> Int {
    return self.nav?.nav.count ?? 0
}



 func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return self.nav?.nav[section]. children.count ?? 0
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "Cell") as! ChildTableViewCell

    cell.name.text = self.nav?.nav[indexPath.section]. children[indexPath.row]

    return cell
}

the arr referees to the children array hope this will help

10
  • Hi, Thanks for you answer, Do you have an idea about the rest of the question? Commented Nov 18, 2018 at 14:21
  • Why do you need different sections?
    – ironRoei
    Commented Nov 18, 2018 at 14:24
  • Because I want the children array to display in a different section, so when I can display them I’m going to make it into a expandable table view Commented Nov 18, 2018 at 14:27
  • This is children for you?: { "name": "Home", "navigationName": "Home", "icon": null, "navigation": { "URI": null, "type": "CUSTOM", "target": "home", "depth": null, "data": null, "filters": {}, "urlStructure": { "title": null, "isFeatured": false, "isCampaign": false } }, "styles": [] }
    – ironRoei
    Commented Nov 18, 2018 at 14:31
  • for me children is: `"children": [ { "name": "New In Mens", "navigationName": "New In Mens", "icon": null, "navigation": { "URI": "/men?facet:new=latest&sort=latest", "type": "CATEGORY", "target": "men", "depth": null, ] Commented Nov 18, 2018 at 14:44

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.