Ios 尝试存储数据时我的代码中出现错误

Ios 尝试存储数据时我的代码中出现错误,ios,swift,Ios,Swift,我明白了 在“数组”上引用实例方法“encode”需要“(item:String?、price:String?、saleprice:String?)符合“Encodable” storeData()函数中出现此错误。我是否在用户默认值中正确保存了元组?如果有人能提供帮助,那就太好了!非常感谢您的帮助 import UIKit let defaults = UserDefaults(suiteName: "com.Saving.Data") struct Product: Codable {

我明白了

在“数组”上引用实例方法“encode”需要“(item:String?、price:String?、saleprice:String?)符合“Encodable”

storeData()
函数中出现此错误。我是否在用户默认值中正确保存了元组?如果有人能提供帮助,那就太好了!非常感谢您的帮助

import UIKit

let defaults = UserDefaults(suiteName: "com.Saving.Data")

struct Product: Codable {
    var title: String
    var price: String
    var salePrice: String
}

class ViewController: UIViewController {

    @IBOutlet weak var tableView: UITableView!

    var items: [(item: String?, price: String?, salesPrice: String?)] = []

    override func viewDidLoad() {
        super.viewDidLoad()
        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
    }

    @IBAction func addButtonTapped(_ sender: Any) {
        let alert = UIAlertController(title: "Product Information", message: nil, preferredStyle: .alert)
            alert.addTextField { (itemTF) in
                itemTF.placeholder = "Item"
            }

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

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

            let action = UIAlertAction(title: "Add", style: .default) { (_) in

                var product : (item: String, price: String, salesPrice: String) = ("","","")

                if let textField1 = alert.textFields?[0], let text = textField1.text {
                    print(text)
                    product.item = text

                }

                if let textField2 = alert.textFields?[1], let text = textField2.text {
                    print(text)
                     product.price = text

                }

                if let textField3 = alert.textFields?[2], let text = textField3.text {
                    print(text)
                    product.salesPrice = text

                }
                self.add(product)
            }

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

       func add(_ product: (item: String, price: String, salesPrice: String)) {
            let index = 0
            items.insert(product, at: index)

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


     func storeData() {

           if let data = try? PropertyListEncoder().encode(items) {
            UserDefaults.standard.set(data, forKey: "savedData")

           }
       }

       func getData() {

        if let data = UserDefaults.standard.data(forKey: "savedData") {
            let items = try! PropertyListDecoder().decode([Product].self, from: data)
            print(items)
           }
       }



}

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
        print(product.price ?? "")
        print(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.92, green:0.92, blue:0.92, 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.reloadData()
        storeData()
    }
}

正如在评论中已经提到的,不可理解的是,为什么要使用与struct
产品
具有相同设计的额外元组。这会导致您的问题

所以去掉元组

申报
项目

var items = [Product]()
将警报操作替换为

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)
}
用替换
添加

  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()
    }
func getData() {
    if let data = UserDefaults.standard.data(forKey: "savedData") {
        do {
            items = try PropertyListDecoder().decode([Product].self, from: data)
            print(items)
            tableView.reloadData()
        } catch { print(error) }
    }
}
getData
替换为

  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()
    }
func getData() {
    if let data = UserDefaults.standard.data(forKey: "savedData") {
        do {
            items = try PropertyListDecoder().decode([Product].self, from: data)
            print(items)
            tableView.reloadData()
        } catch { print(error) }
    }
}
旁注:请注意,代码将数据保存在标准
UserDefaults
中,而不是您的自定义套件中

最后——与问题无关——在
tableView:commit editingStyle:
replace中获得一个漂亮的动画

tableView.reloadData()


当您有一个具有相同属性的结构时,为什么要在数组中使用元组?我建议改为使用该结构并使其符合CodableCannot将类型为“(item:String,price:String,saleprice:String)”的值转换为预期的参数类型“Product”,当我更改var items=[(items:…ect to var items=[Product]()我在addButtonTapped使用未解析标识符“alert”时遇到此错误。这只是操作。当然,您必须保留行以创建警报控制器并添加文本字段。我在cellForRowAt中遇到此错误。“无法将“Product”类型的值分配给“String”类型?”“@vadianYou正在将
product
分配给标签(并且您更改了问题中的代码)。这是错误的。您必须将一个属性分配给标签,例如
cell.textlab?.text=product.title
。重新使用单元格,
let cell=UITableViewCell()
是不合适的。