[Solved] Im getting an error at cellForRowAt and im not sure why


cell.textLabel?.text can only show a String object, not other objects.

It will be product.item or product.price or product.salesPrice or all in one line. (based on your requirement).

Make sure the value of product is not nil.

cell.textLabel?.text = "\(product.item) \(product.price) \(product.salesPrice)"

The full code you can try this:

class ViewController: UIViewController, UIAdaptivePresentationControllerDelegate {

    @IBOutlet weak var tableView: UITableView!

    var items:[Product]? = []

    // VIEW LOAD
    override func viewDidLoad() {
        super.viewDidLoad()

        if #available(iOS 13.0, *) {
            self.isModalInPresentation = true
        }

        getData()
    }
    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(true)
        getData()
    }

    override func viewDidDisappear(_ animated: Bool) {
        super.viewDidDisappear(true)
        storeData()
    }
    override var prefersStatusBarHidden: Bool {
        return true
    }
    // ADD ITEMS
    @IBAction func addButtonTapped(_ sender: Any) {
        let alert = UIAlertController(title: "Product Information", message: nil, preferredStyle: .alert)
        alert.addTextField { (itemTextField) in
            itemTextField.placeholder = "Item"
        }
        alert.addTextField { (priceTextField) in
            priceTextField.placeholder = "Price"
        }

        alert.addTextField { (salePriceTextField) in
            salePriceTextField.placeholder = "Sale Price"
        }

        let action = UIAlertAction(title: "Add", style: .default) { (_) in
            let item = alert.textFields?[0].text ?? ""
            let price = alert.textFields?[1].text ?? ""
            let salesPrice = alert.textFields?[2].text ?? ""

            let product = Product(item: item, price: price, salesPrice: salesPrice)
            self.addProduct(product)
        }

        alert.addAction(action)
        present(alert, animated: true)
        storeData()

    }

    func addProduct(_ product: Product) {
        let index = 0
        items?.insert(product, at: index)

        let indexPath = IndexPath(row: index, section: 0)
        tableView.insertRows(at: [indexPath], with: .left)
        storeData()
    }

    //STORE DATA
    func storeData() {
        UserDefaultUtil.saveData(products: items)
    }

    func getData() {
        items = UserDefaultUtil.loadProducts()

    }

}

//EXTENSION
extension ViewController: UITableViewDataSource {
    func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return items!.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = UITableViewCell()
        let product = items![indexPath.row]
        cell.textLabel?.text = "\(product.item!) \(product.price) \(product.salesPrice)"

        cell.contentView.backgroundColor = UIColor(red:0.92, green:0.92, blue:0.92, alpha:1.0)
        cell.textLabel?.textColor = UIColor(red:0.13, green:0.13, blue:0.13, alpha:1.0)
        tableView.separatorColor = UIColor(red:0.13, green:0.13, blue:0.13, alpha:1.0)


        return cell
    }

    func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
        guard editingStyle == .delete else { return }
        items?.remove(at: indexPath.row)
        tableView.deleteRows(at: [indexPath], with: .fade)
        storeData()
    }
}

class UserDefaultUtil {

    private static let Key = "savedData"

    private static func archivePeople(people : [Product]) -> NSData {

        return NSKeyedArchiver.archivedData(withRootObject: people as NSArray) as NSData
    }

    static func loadProducts() -> [Product]? {

        if let unarchivedObject = UserDefaults.standard.object(forKey: Key) as? Data {

            return NSKeyedUnarchiver.unarchiveObject(with: unarchivedObject as Data) as? [Product]
        }

        return nil
    }

    static func saveData(products : [Product]?) {
        let archivedObject = archivePeople(people: products!)
        UserDefaults.standard.set(archivedObject, forKey: Key)
        UserDefaults.standard.synchronize()
    }

}

class Product: NSObject, NSCoding {
    var item: String?
    var price: String?
    var salesPrice: String?

    required init(item:String, price:String, salesPrice: String) {
        self.item = item
        self.price = price
        self.salesPrice = salesPrice
    }

    required init(coder aDecoder: NSCoder) {
        self.item = aDecoder.decodeObject(forKey: "item") as? String
        self.price = aDecoder.decodeObject(forKey: "price") as? String
        self.salesPrice = aDecoder.decodeObject(forKey: "salesPrice") as? String
    }

    public func encode(with aCoder: NSCoder) {
        aCoder.encode(item, forKey: "item")
        aCoder.encode(price, forKey: "price")
        aCoder.encode(salesPrice, forKey: "salesPrice")
    }
}

7

solved Im getting an error at cellForRowAt and im not sure why