通过核心数据关系改变属性值

时间:2016-02-12 05:46:03

标签: xcode swift nsfetchedresultscontroller relationships managedobjectcontext

我正在努力更新存储在具有"一对多"的实体中的值。与另一个实体的关系。

我的项目是一个预算编制应用。使用NSFetchedResultsController,我可以成功添加一个事务(填充在表中)并删除FRC自动保存的事务。

我有一个实体,用于存储具有属性的交易" name"和"金额",我有一个单独的实体,有一个属性" theDate" (NSDate)存储交易日期。

之所以分开,是因为我相信这会在组织上使其更简单 - 许多交易可以在同一天发生。

在下面我创建实体并在创建新事务后存储值,然后设置关系:

 @IBAction func done(segue: UIStoryboardSegue) {
    let addTransactionVC = segue.sourceViewController as! AddTransaction
    let newTrans = addTransactionVC.newTransaction
    let date = addTransactionVC.datePicker.date

    // Create Entities
    let entity = NSEntityDescription.entityForName("DailyTransactions", inManagedObjectContext: self.managedContext)
    let relatedEntity = NSEntityDescription.entityForName("TransDates", inManagedObjectContext: self.managedContext)

    // Initialize Record
    let record = NSManagedObject(entity: entity!, insertIntoManagedObjectContext: self.managedContext)
    let recordDate = NSManagedObject(entity: relatedEntity!, insertIntoManagedObjectContext: self.managedContext)

    // Is new transaction being created or an old one being edited?
    if !addTransactionVC.isEditingTransaction {

        // Populate Record
        record.setValue(newTrans.name, forKey: "transName")
        record.setValue(newTrans.amount, forKey: "transAmount")
        recordDate.setValue(date, forKey: "theDate")

        // Create Relationship of Date to Transaction
        record.setValue(recordDate, forKey: "date")

    } else {

        // If user was editing a transaction:
        let updatedObject = addTransactionVC.managedObject
        let newDate = addTransactionVC.datePicker.date

        // How do I change the date associated with this transaction?
        updatedObject.setValue(newTrans.name, forKey: "transName")
        updatedObject.setValue(newTrans.amount, forKey: "transAmount")

        // This line was meant to access the attribute in the "date" relationship:
        updatedObject.setValue(newDate, forKey: "date")

else以上的所有内容都可以。如果选择要编辑的单元格(事务),则else触发后。这一行:updatedObject.setValue(newDate, forKey: "date")旨在简单地更新" theDate" TransDates实体的属性(" date"是关系的名称)。但是我现在看到为什么那不起作用。

所以我在else语句中尝试了这个:

        let fetchRequestDates = NSFetchRequest(entityName: "TransDates")

        do {

            let dateObjects = try self.managedContext.executeFetchRequest(fetchRequestDates) as! [TransDates]
            for dateObject in dateObjects {

                // These 2 lines were to test that a date was being returned:
                let tempDate = dateObject.theDate as! NSDate
                print("dateObject is:\n\(String(tempDate))")

                if dateObject.valueForKey("theDate") as! NSDate == newDate {
                    updatedObject.setValue(dateObject, forKey: "date")
                    break
                }
            }

        } catch let error as NSError {
            print("Could not fetch \(error), \(error.userInfo)")
        }

我认为上面只会返回所有TransDates对象的数组,如果找到了匹配项(b / w数组中的内容和新的NSDate),updatedObject会被添加到其中,否则我会添加一些代码来创建newDate作为新的NSManagedObject等。

然而,当执行if dateObject.valueForKey("theDate") as! NSDate == newDate {时会发生这种情况:"致命错误:在展开可选值&#34时意外地发现nil。

我的两个问题:

  1. 就我想要完成的事情而言 - 更新/更改与交易相关联的日期(如果日期已经存在且包含其他交易,此交易只会转移到加入他们),这是最好的方式吗?

  2. 我的关系目的/功能是否都错了?

  3. 抱歉这个冗长的问题,但我已经被困在这里好几天了。所以提前谢谢!

1 个答案:

答案 0 :(得分:0)

您收到此错误的原因是您尝试强制解包nil值。您应该使用if let语句:

if let date dateObject.valueForKey("theDate") as? NSDate {
    if date == newDate {
        ...
    }
}