ios - 用户输入的值保存到核心数据(?)但未出现在 TableView 中

标签 ios swift uitableview core-data

我一直在努力解决用户输入的值在我正在处理的项目的表格 View 中正确显示的问题。

我获取用户输入值的方法是让用户在文本字段中输入信息(公司名称、股票代码和 Logo 的 URL),然后在以下情况下调用 handleSave()按下完成按钮:

func handleSave() {

let newCompanyName = nameTextField.text
guard let newCompanyStockSymbol = stockTextField.text else {
    // handle the error how you see fit
    print("error getting text from field")
    return
}
let newCompanyLogo = logoTextField.text

var newCompanyStockPrice = ""

// Fetch stock price from symbol provided by user for new company
let url = URL(string: "https://query.yahooapis.com/v1/public/yql?q=select%20symbol%2C%20Ask%2C%20YearHigh%2C%20YearLow%20from%20yahoo.finance.quotes%20where%20symbol%20in%20(%22\(newCompanyStockSymbol)%22)&format=json&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys")!
let task = URLSession.shared.dataTask(with: url) { (data, response, error) in
    if error != nil {
        print(error!)
    } else if let httpResponse = response as? HTTPURLResponse, httpResponse.statusCode == 200 {
        let json = JSON(data: data!)
        if let quotes = json["query"]["results"]["quote"].array {
            for quote in quotes {
                let ask = quote["Ask"].stringValue
                newCompanyStockPrice = ask
            }
        }
    }
    self.viewController?.save(name: newCompanyName!, logo: newCompanyLogo!, stockPrice: newCompanyStockPrice)
    //self.viewController?.tableView.reloadData()
}
task.resume()



let cc = UINavigationController()
let companyController = CompanyController()
cc.viewControllers = [companyController]
present(cc, animated: true, completion: nil)
}

依次调用此save 函数,该函数将值保存到托管上下文中。

func save(name: String, logo: String, stockPrice: String) {

guard let appDelegate =
    UIApplication.shared.delegate as? AppDelegate else {
        return
}

let managedContext =
    appDelegate.persistentContainer.viewContext

let entity =
    NSEntityDescription.entity(forEntityName: "Company",
                               in: managedContext)!
let company = NSManagedObject(entity: entity,
                              insertInto: managedContext)


company.setValue(stockPrice, forKey: "stockPrice")
company.setValue(name, forKey: "name")
company.setValue(logo, forKey: "logo")


do {
    try managedContext.save()
    companies.append(company)
} catch let error as NSError {
    print("Could not save. \(error), \(error.userInfo)")
}

tableView.reloadData()
}

如果我在 handleSave() 中调用 self.viewController?.save(name: newCompanyName!, logo: newCompanyLogo!, stockPrice: newCompanyStockPrice) 时设置断点> 函数,我可以看到所有三项(newCompanyNamenewCompanyLogonewCompanyStockPrice)都有值。但是当我尝试在 cellForRow 中设置新公司时,它没有出现在我的表格 View 上:

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

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

    let cell = tableView.dequeueReusableCell(withIdentifier: cellId, for: indexPath) as! Cell
    let company = companies[indexPath.row]
    let stock = company.value(forKey: "stockPrice") as? String

    // Company name labels
    cell.textLabel?.text = company.value(forKey: "name") as? String


    // Stock price underneath
    if let stock = stock {
        cell.detailTextLabel?.text = "Current stock price: \(stock)"
    }

    // Logos
    DispatchQueue.main.async {
    if let url = NSURL(string: (company.value(forKey: "logo") as? String)!) {
        if let data = NSData(contentsOf: url as URL) {
            cell.logoView.image = UIImage(data: data as Data)
        } else {
            cell.logoView.image = UIImage(named: "noImage")
        }
    }
    }
    return cell
}

编辑:viewWillAppear

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)

    //1
    guard let appDelegate =
        UIApplication.shared.delegate as? AppDelegate else {
            return
    }

    let managedContext =
        appDelegate.persistentContainer.viewContext

    //2
    let fetchRequest =
        NSFetchRequest<NSManagedObject>(entityName: "Company")

    //3
    do {
        companies = try managedContext.fetch(fetchRequest)
    } catch let error as NSError {
        print("Could not fetch. \(error), \(error.userInfo)")
    }

}

最佳答案

我建议将重新加载数据的调用明确地放在主队列上。在我看来,您正在从 dataTask 完成处理程序中调用 func save(name: String, logo: String, stockPrice: String) ,然后调用 reloadData 在该线程上。

因此,在 save 函数中,将其包装如下:

DispatchQueue.main.async { [weak self] in 
    self?.tableView.reloadData()
}

关于ios - 用户输入的值保存到核心数据(?)但未出现在 TableView 中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42179860/

相关文章:

来自 imagePickerController : didFinishPickingMediaWithInfo 的 ios pushViewController

ios - 自动布局,UiScrollView 内的 UITableView 不会增长

objective-c - 调整 UITableView 的大小

ios - 在 Objective C 的 FooterTableViewCell 中放置 View 的问题

ios - SwiftUI-计时器不会在0处停止

ios - 在 ios dev Schema 中禁用 firestore

swift - 有没有办法在 Swift 中获得一个 _stable_ 泛型类名?

swift - NSScrollView 不滚动

swift - 数组元素分配导致昂贵的 _ArrayBuffer Protocol.init(copying :)

swift - 将变量从 TableView Controller 获取到自定义单元格