在NStableView中显示和使用核心数据

时间:2018-07-24 02:29:50

标签: swift macos core-data nstableview

背景:我已经在自学SWIFT,iOS和Mac OS几周了,并且一直在尝试为从数据库中获取的Mac OS组装一个“价格计算器”纸并使用选定的属性选择一张纸。用户将能够从属性列表中进行选择,例如:尺寸,重量,表面处理,颜色和品牌。从那里可以使用通用算法计算出纸价。

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

问题:我有一个tableView正在获取核心数据并显示不同纸张的可用 –至少应该这样做。为了进行测试,我已经创建了一个“添加纸张”按钮,该按钮生成随机纸张并将其添加到数据库中。我知道这是在创建随机的随机纸张,因为我能够在输出中显示它。但是我实际上不知道它是否可以保存。

我遇到的问题是,当我尝试刷新表并将数据显示到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)")
        }
    }
}

1 个答案:

答案 0 :(得分:0)

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

let paperSpecs = papers[row]

您可能还想研究NSFetchedResultsController,这在处理Core数据和表视图时非常有用。