核心数据实体唯一约束不起作用

时间:2016-05-19 03:53:06

标签: ios swift core-data constraints

我正在尝试使用新的Entity Constraints检查器在核心数据中设置约束(使项目的名称唯一)。我读过的所有内容都说它非常简单 - 设置约束并处理错误。我没有收到任何错误,可以根据需要添加相同的条目。

该应用确实需要IOS 9.0,Xcode工具要求设置为7.0

约束category1Name是一个String。

我的addItem代码是:

FileSystemStorage

AppDelegate保存是标准的:

Storage

这是核心数据约束:

enter image description here

此应用已启用iCloud。

managedObjectContext合并策略设置为NSMergeByPropertyObjectTrumpMergePolicy

func addNewRecord() {

    //check to be sure the entry is not empty
    if (categoryTextField.text == "") {

        //prompt requiring a name
        let ac = UIAlertController(title: nil, message: "Name Required", preferredStyle: .Alert)
        ac.addAction(UIAlertAction(title: "Ok", style: .Default, handler: nil))
        self.presentViewController(ac, animated: true, completion: nil)

    } else {

    let newManagedObject = NSEntityDescription.insertNewObjectForEntityForName("Category1", inManagedObjectContext: kAppDelegate.managedObjectContext) as! Category1

    newManagedObject.category1Name = categoryTextField.text
    newManagedObject.category1Description = categoryTextView.text

    //bunch more items...

    //save it
    kAppDelegate.saveContext()
    makeEntryFieldsEnabledNO()
    performSegueWithIdentifier("unwindToCategoriesTableViewController", sender: self)

    }//if  else

}//addNewRecord

任何指导都将不胜感激。

3 个答案:

答案 0 :(得分:3)

2020年的CoreData ...

Apple似乎终于解决了疯狂的Xcode问题,即您在数据模型文件中所做的更改实际上并没有改变,这不是玩笑。

放在一边,当前公式似乎是:

在您的核心数据单例中...

    container = NSPersistentContainer(name: _nom)
    
    // during development, right HERE likely delete the sql database file
    // and start fresh, as described here stackoverflow.com/a/60040554/294884
    
    container.loadPersistentStores { storeDescription, error in
        if let error = error {
            print("\n ERROR LOADING STORES! \(error) \n")
        }
        else {
            print("\n  STORES LOADED! \(storeDescription) \n")
        }
    
        self.container.viewContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy
        self.container.viewContext.automaticallyMergesChangesFromParent = true
    }

您必须使用合并策略,并且会自动合并。

然后在您的数据模型文件中

  1. 除非每个关系都具有
  2. 逆向,并且
  3. 正确设置
  4. “一个或多个”
  5. (几乎可以肯定,除了非常不寻常的异常数据之外),每个实体的唯一ID均表示为约束条件

然后,当您添加新数据时,您必须

  1. 使用新的背景上下文提供的方便的核心数据功能
  2. 因此,切勿尝试创建自己的单独线程
  3. 仔细检查您已完成(1)和(2)!
  4. 当您添加一些实体时,必须在perform
  5. 并且当您完成添加实体时(即在新线程上),您必须同时仍在表演中 ...
  6. 做一个performAndWait,它做两件事
  7. 保存新项目(在新的线程上),然后
  8. 保存新项目(在主视图线程上)
  9. 自然地,对于7和8,您都必须在保存之前检查.hasChanges

容易吗?

类似

let pm = core.container.newBackgroundContext()
pm.perform {
    for onePerson in someNewData {
        ... create your new CDPerson entity ...
    }
    pm.bake()
}

请注意,烘焙例程位于Perform块内,

它看起来像这样:

func bake() {
    self.performAndWait {
        if self.hasChanges {
            do {
                try self.save()
            }
            catch {
                print("bake disaster type 1 \(error)")
            }
        }
        
        // OPTIONALLY, SEE BELOW
        if core.container.viewContext.hasChanges {
            do {
                try core.container.viewContext.save()
            }
            catch {
                print("bake disaster type 2 \(error)")
            }
        }
        // OPTIONALLY, SEE BELOW
    }
}

为清楚起见,请注意函数pm.bake中的bake() ...,上半部的self实际上是为循环创建的newBackgroundContext在表演里面。

请注意,这几天您甚至不需要保存到主上下文中

现在,automaticallyMergesChangesFromParent似乎工作得很好,如果您“执行上面长长的列表中的所有操作”。

•在上面的烘烤中,添加一些打印行以查看保存到viewContext的内容。您会看到什么都没有保存。引擎中的子级/子级关系都可以正确完成

•因此,实际上,您实际上可以忽略代码的该部分。您所要做的就是

func bake() {
    self.performAndWait {
        if self.hasChanges {
            do {
                try self.save()
            }
            catch {
                print("bake disaster type 1 \(error)")
            }
        }
}

答案 1 :(得分:2)

上面pbasdf的评论似乎是正确的。检查员的约束不保存。我使用了提供的链接中建议的两种方法 - 我添加了约束,我更改了另一个属性,执行了文件保存,然后更改了该属性并再次保存文件。约束现在按照我的预期行事。我会将此标记为已回答。 pbasdf应该得到信用。

答案 2 :(得分:0)

如果您想在出现合并冲突时遇到错误并手动处理它们,那么您需要将策略更改为NSErrorMergePolicy,您将收到错误,并在用户信息中找到解决合并冲突所需的对象ID,否则它将根据指定的合并策略进行合并和保存。 如果要覆盖属性和关系,则设置的策略将覆盖对象属性而不覆盖关系,然后指定NSMergeByPropertyObjectTrumpMergePolicy。