0

I am making a shopping app but I've come to a problem.

So far I've been json parsing, making a the tableview cell but I've come to an error where it says out of range:

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

    // Configure the cell...

    cell.userLbl.text = namee[indexPath.row]  //Index out of range
    cell.passLbl.text = myprice[indexPath.row]
    
    let imagedata = try! Data(contentsOf: mySecond[indexPath.row].imageUrl!)
    cell.tablecellimageview.image = UIImage(data: imagedata)
    
    return cell
}

This is my display shop table cell:

class DisplayShopTableCellTableViewCell: UITableViewCell {
    
    @IBOutlet weak var userLbl: UILabel!
    @IBOutlet weak var passLbl: UILabel!
    @IBOutlet weak var tablecellimageview: UIImageView!

Parsing

func extracted(){
    guard let url = URL(string: "http://rajeshrmohan.com/sport.json")
    else {
        return
    }
    
    let task = URLSession.shared.dataTask(with: url){
        (data,response,error) in
        guard let dataResponse = data,
              error == nil else {
            print(error?.localizedDescription ?? "Response Error")
            return
        }
        
        do {
            let decoder = JSONDecoder()
            let model = try decoder.decode(FullClothes.self, from: dataResponse)
            //print(model)
            
            for i in 0..<model.item.count{
                self.namee.append(model.item[i].name!)
                self.myprice.append(String(model.item[i].price!))
                self.myphoto.append(model.item[i].image!)
            }
            DispatchQueue.main.async {
                self.tableView.reloadData()
            }
        }
        catch let parsingError {
            print("Error", parsingError)
        }
    }
    task.resume()
}
Nimantha
  • 6,405
  • 6
  • 28
  • 69
KAKEN
  • 11
  • 3
  • The code written under the `cellForRowAt` delegate method doesn't quite make sense. Why are you using two separate arrays to make the cell? – El Tomato Nov 17 '21 at 04:51
  • to store the data and to be used in the parsing above no? – KAKEN Nov 17 '21 at 05:08

1 Answers1

1

I think the parsing is done in a wrong way, additionally, as El Tomato commented, why using multiple arrays for constructing a cell, one more comment, configuring cell shouldn't be done inside cellForRowAt, it would be better done within cell itself. Check the following code snippet and let me know if you need any help withh it.

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

    // Configure the cell...
    cell.bind(self.myData[indexPath.row])
    return cell
}

class DisplayShopTableCellTableViewCell: UITableViewCell {
    @IBOutlet weak var userLbl: UILabel!
    @IBOutlet weak var passLbl: UILabel!
    @IBOutlet weak var tablecellimageview: UIImageView!
    func bind(_ cellData: Item) {
        self.userLbl.text = cellData.name
        self.passLbl.text = String(cellData.price)
        guard let imageURL = URL(string: "\(cellData.image)") else {
            preconditionFailure("Invalid static URL string: \(cellData.image)")
        }
        guard let imagedata = try? Data(contentsOf: imageURL) else {
            return
        }
        self.tablecellimageview.image = UIImage(data: imagedata)
    }
}

struct Item: Decodable {
    let name: String
    let price: Float
    let image: String
}

func extracted() {
    guard let url = URL(string: "http://rajeshrmohan.com/sport.json")
    else {
        return
    }
    
    let task = URLSession.shared.dataTask(with: url){
        (data,response,error) in
        guard let dataResponse = data,
              error == nil else {
            print(error?.localizedDescription ?? "Response Error")
            return
        }
        
        do {
            let decoder = JSONDecoder()
            let items: [Item] = try decoder.decode([Item].self, from: dataResponse)
            //print(model)
            
            for i in 0..<items.count {
                self.myData.append(items[i])
            }
        }
        catch let parsingError {
            print("Error", parsingError)
        }
    }
    task.resume()
}

Finally, try as far as you can to avoid force casting, check this question for further insights about force casting.

Optional chaining would be helpful too.

Nimantha
  • 6,405
  • 6
  • 28
  • 69