首页 > 解决方案 > 在 NSTableView 中显示和使用核心数据

问题描述

背景:几周以来,我一直在自学 Swift、iOS 和 macOS,我一直在尝试为 macOS 组合一个“价格计算器”,它从纸张数据库中抓取并使用选定的属性来选择一块纸。用户将能够从属性列表中进行选择,例如:尺寸、重量、表面处理、颜色和品牌。从那里它将使用一般算术计算纸张的价格。

起初我考虑使用 SQLite 或类似的数据库样式程序来填充我的计算器 - 但用户需要能够自己填充 Paper 数据库。因此,我开始使用 Core Data。

问题:我有一个表格视图,它获取核心数据并显示不同的可用论文——或者至少它应该这样做。为了进行测试,我创建了一个“添加纸张”按钮,该按钮生成随机纸张并将其添加到数据库中。我知道这是在创建随机随机纸,因为我能够在输出中显示它。但我真的不知道它是否节省。

我遇到的问题是,当我尝试刷新表格并将数据显示到 tableView 时……它要么由于 Nil 值而崩溃,要么它没有添加到 tableView。

我得出的结论是,我可能在表格中显示错误的数据 - 或者 - 我没有正确保存数据 - 或者 - 我没有正确获取数据。

iOS 的在线资源仅对 Mac OS 有很大的帮助,对此的任何帮助将不胜感激。我的代码可以在下面找到,在此先感谢您:注意:我正在使用 CoreData 中的样板 AppDelegate 文件。

在 ViewController 中定义:

private var papers = [FlatPaper]()
private var appDelegate = NSApplication.shared.delegate as! AppDelegate
private let context = (NSApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext

添加随机纸张按钮(用于测试):

@IBAction func addPaper(_ sender: NSButton) {
    let data = PaperData()
    let paper = FlatPaper(entity: FlatPaper.entity(), insertInto: context)
    paper.paperSize = data.paperSize
    paper.paperWeight = data.paperWeight
    paper.paperBrand = data.paperBrand
    paper.paperColor = data.paperColor
    paper.paperFinish = data.paperFinish
    paper.paperPrice = data.paperPrice
    appDelegate.saveAction(paper)
    papers.append(paper)
    print("Add Paper Button Pressed. \(paper)")
    refresh()
    tableView.reloadData()
}

扩展 NSTableDelegate 和 NSTableDataSource:

extension ViewController: NSTableViewDataSource, NSTableViewDelegate {

    // Mark: - Specifying how many rows
    func numberOfRows(in tableView: NSTableView) -> Int {
        return papers.count
        }

    // Mark: - Populating the Columns and Rows with Data
    func tableView(_ tableView: NSTableView, objectValueFor tableColumn: NSTableColumn?, row: Int) -> Any? {
        let paperSpecs = papers[row]
        
        if tableColumn!.title == "Paper Size" {
            return paperSpecs.paperSize
        } else if tableColumn!.title == "Paper Weight" {
            return paperSpecs.paperWeight
        } else if tableColumn!.title == "Paper Brand" {
            return paperSpecs.paperBrand
        } else if tableColumn!.title == "Paper Color" {
            return paperSpecs.paperColor
        } else if tableColumn!.title == "Paper Finish" {
            return paperSpecs.paperFinish
        } else {
            return paperSpecs.paperPrice
        }
    }

    // Mark: - Refresh Method for reloading all of the data
    private func refresh() {
        do {
            papers = try context.fetch(FlatPaper.fetchRequest())
        } catch let error as NSError {
            print("Could not fetch. \(error), USER INFO: \(error.userInfo)")
        }
    }
}

标签: swiftmacoscore-datanstableview

解决方案


tableview:objectValueFor您应该使用 row 参数而不是创建一个新的(空)实例从您的数组中获取您的纸张规格对象。

let paperSpecs = papers[row]

您可能还想查看NSFetchedResultsController,它在处理核心数据和表视图时非常有用。


推荐阅读