Home > OS >  How to display nested JSON data in tableView [closed]
How to display nested JSON data in tableView [closed]

Time:09-17

JSON Response Im getting from api

{
    "status": "Success",
    "data": [
        {
            "site_id": 1,
            "site_created_on": "2021-08-10T16:37:00.000Z",
            "site_down": 0,
            "site_down_from": "Dec 31 1999  6:30PM",
            "site_down_to": "Dec 31 1999  6:30PM",
            "site_name": "Crch",
            "site_url": "http://crch.net",
            "instant_account": 0,
            "status": 1,
            "img": "assets\\images\\uploads\\site\\favicon-dacd04641be3ff6abf8407b5ef35c0de.png",
            "gamedata": [
                {
                    "game_id": 1,
                    "isactive": 1,
                    "coins": 100,
                    "name": "Teenpatti",
                    "status": 1,
                    "site_id": 1
                },
                {
                    "game_id": 2,
                    "isactive": 1,
                    "coins": 500,
                    "name": "Cricket",
                    "status": 1,
                    "site_id": 1
                },
                {
                    "game_id": 3,
                    "isactive": 1,
                    "coins": 1000,
                    "name": "Soccer",
                    "status": 1,
                    "site_id": 1
                },
                {
                    "game_id": 4,
                    "isactive": 1,
                    "coins": 1000,
                    "name": "Tennis",
                    "status": 1,
                    "site_id": 1
                },
                {
                    "game_id": 5,
                    "isactive": 1,
                    "coins": 1000,
                    "name": "Horse",
                    "status": 1,
                    "site_id": 1
                },
                {
                    "game_id": 6,
                    "isactive": 1,
                    "coins": 1000,
                    "name": "Grey",
                    "status": 1,
                    "site_id": 1
                }
            ]
        }
    ]
}

I wan to print all the data present inside game data Array

Currently i have the code as this manner:

DataModel :

class WebSiteDataModel: Codable {
    let status: String?
    let data: [Datum]?

    init(status: String?, data: [Datum]?) {
        self.status = status
        self.data = data
    }
}

// MARK: - Datum
class Datum: Codable {
    let siteID: Int?
    let siteCreatedOn: String?
    let siteDown: Int?
    let siteDownFrom, siteDownTo, siteName: String?
    let siteURL: String?
    let instantAccount, status: Int?
    let img: String?
    let gamedata: [Gamedatum]?

    enum CodingKeys: String, CodingKey {
        case siteID = "site_id"
        case siteCreatedOn = "site_created_on"
        case siteDown = "site_down"
        case siteDownFrom = "site_down_from"
        case siteDownTo = "site_down_to"
        case siteName = "site_name"
        case siteURL = "site_url"
        case instantAccount = "instant_account"
        case status, img, gamedata
    }

    init(siteID: Int?, siteCreatedOn: String?, siteDown: Int?, siteDownFrom: String?, siteDownTo: String?, siteName: String?, siteURL: String?, instantAccount: Int?, status: Int?, img: String?, gamedata: [Gamedatum]?) {
        self.siteID = siteID
        self.siteCreatedOn = siteCreatedOn
        self.siteDown = siteDown
        self.siteDownFrom = siteDownFrom
        self.siteDownTo = siteDownTo
        self.siteName = siteName
        self.siteURL = siteURL
        self.instantAccount = instantAccount
        self.status = status
        self.img = img
        self.gamedata = gamedata
    }
}

// MARK: - Gamedatum
class Gamedatum: Codable {
    let gameID, isactive, coins: Int?
    let name: String?
    let status, siteID: Int?

    enum CodingKeys: String, CodingKey {
        case gameID = "game_id"
        case isactive, coins, name, status
        case siteID = "site_id"
    }

    init(gameID: Int?, isactive: Int?, coins: Int?, name: String?, status: Int?, siteID: Int?) {
        self.gameID = gameID
        self.isactive = isactive
        self.coins = coins
        self.name = name
        self.status = status
        self.siteID = siteID
    }
}

Controller:

var newArray = Datum

let url = baseUrl

        APIClient<WebSiteDataModel>().API_GET(Url: url, Params: noParams, Authentication: true, Progress: false, Alert: true, Offline: false, SuperVC: self, completionSuccess:{(modelResponse) in
           
            if let status = modelResponse.status, status == "Success"
            {
                self.newArray = modelResponse.data ?? []
                self.expandableTableView.reloadData()
            }
            else
            {
                
            }
           
        }) {(failed) in
            
        }

TableView:

extension IdsViewController: ExpyTableViewDataSource {
    func tableView(_ tableView: ExpyTableView, expandableCellForSection section: Int) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "ExpandPLTableViewCell") as! ExpandPLTableViewCell
        let obj = newArray[section]
        cell.siteName.text = obj.siteName
        return cell
    }
    
    func tableView(_ tableView: ExpyTableView, canExpandSection section: Int) -> Bool {
        return ExpyTableViewDefaultValues.expandableStatus
    }
}

extension IdsViewController {
    func numberOfSections(in tableView: UITableView) -> Int {
        return newArray.count
    }
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 2
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        let cell = tableView.dequeueReusableCell(withIdentifier: String(describing: PLSpecificationTableViewCell.self)) as! PLSpecificationTableViewCell
        let obj = newArray[indexPath.section].gamedata?[indexPath.row]
        print(obj?.name ?? "")
        return cell
    }
}

extension IdsViewController
{
    //Tells the delegate a row is selected.
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
    {
        tableView.deselectRow(at: indexPath, animated: false)
        
        print("DID SELECT row: \(indexPath.row), section: \(indexPath.section)")
    }
    
    //Asks the delegate for the height to use for a row in a specified location.
    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat
    {
        
        if indexPath.row != 0 {
            let indexPathRow = self.indexPathRowDetails(indexPath: indexPath)
            
            if indexPath.row % 2 == 0
            {
                if newebsiteArray.isExpanded(section: indexPath.section, row: indexPathRow)
                {
                    return UITableView.automaticDimension
                }
                else
                {
                    return 0
                }
            }
        }
        return UITableView.automaticDimension
    }
}

I want to print all the present in side gamedata Array but getting only one record.Please help me to print all the data

Thank You

CodePudding user response:

First of all declare at least all arrays as non-optional for example

let data: [Datum]

and

let gamedata: [Gamedatum]

and the data source array

var newArray = [Datum]()

Then the table view data source methods are

extension IdsViewController {
    func numberOfSections(in tableView: UITableView) -> Int {
        return newArray.count
    }
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return newArray[section].gamedata.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        let cell = tableView.dequeueReusableCell(withIdentifier: String(describing: PLSpecificationTableViewCell.self)) as! PLSpecificationTableViewCell
        let obj = newArray[indexPath.section].gamedata[indexPath.row]
        print(obj.name ?? "")
        return cell
    }
}

Side note: If you are able to add the .convertFromSnakeCase key decoding strategy to your JSONDecoder the Codable classes can be reduced to these structs

struct WebSiteDataModel: Decodable {
    let status: String
    let data: [Datum]
}

// MARK: - Datum
struct Datum: Decodable {
    let siteId: Int
    let siteCreatedOn: String
    let siteDown: Int
    let siteDownFrom, siteDownTo, siteName: String
    let siteUrl: String
    let instantAccount, status: Int
    let img: String
    let gamedata: [Gamedatum]
}

// MARK: - Gamedatum
struct Gamedatum: Decodable {
    let gameId, isactive, coins: Int
    let name: String
    let status, siteId: Int
}

And you should consider the case if status is not "Success"

  • Related