如何在 CoreData 中保存多个条目?

Posted

技术标签:

【中文标题】如何在 CoreData 中保存多个条目?【英文标题】:How to save multiple entries in CoreData? 【发布时间】:2016-03-23 04:20:48 【问题描述】:

我有以下代码可以正常执行。问题是它只保存最后一个条目(“Jack Daniels”,3)。如何更改它以保存所有三个条目?

let employees = NSEntityDescription.insertNewObjectForEntityForName("Employees", inManagedObjectContext: managedObject)

employees.setValue("John Doe", forKey: "employeename")
employees.setValue(1, forKey: "id")
employees.setValue("Jane Doe", forKey: "employeename")
employees.setValue(2, forKey: "id")
employees.setValue("Jack Daniels", forKey: "employeename")
employees.setValue(3, forKey: "id")

do 
    try managedObject.save()
 catch 
    print("problem saving")

【问题讨论】:

您正在更改同一对象上的值。所以它只会保存最后输入的数据。您必须创建不同的对象并设置值。 【参考方案1】:

斯威夫特 4.1。您不需要将保存代码放在 for 循环中。只需插入所有输入,然后一次性保存。

 let appDelegate = UIApplication.shared.delegate as! AppDelegate
    let context = appDelegate.persistentContainer.viewContext
    let entity = NSEntityDescription.entity(forEntityName: "Employees", in: context)

    let employeeNames = ["John Doe", "Jane Doe", "Jack Daniels"]

    for (index, employee) in employeeNames.enumerated() 
      let newUser = NSManagedObject(entity: entity!, insertInto: context)
      newUser.setValue(employee, forKey: "employeename")
      newUser.setValue(index, forKey: "id")
    

    do 
      try context.save()
     catch 
      print("Failed saving")
    

 // Alternative You can create your Entity class as below and insert entries.

    import CoreData
    class Employees: NSManagedObject 
      @NSManaged var employeename: String
      @NSManaged var id: String

      func addNameAndId(name: String = "", id: String = "") throws 
        if name.count > 0 
          self.employeename = name
          self.id = id
         else  
          throw NSError(domain: "", code: 100, userInfo: nil)
        
      
    

    // Now time to insert data

    let employeeNames = ["John Doe", "Jane Doe", "Jack Daniels"]
     for name in employeeNames 
        guard let emp = NSEntityDescription.insertNewObject(forEntityName: "Employees", into: context) as? Employees else 
                  print("Error: Failed to create a new Film object!")
                  return
                
                do 
                  try emp.addNameAndId(name: name, id: "0")
                 catch 
                  print("Error: \(error)\nThe quake object will be deleted.")
                  context.delete(emp)
                
        

    // Save all the changes just made and reset the taskContext to free the cache.
          if context.hasChanges 
            do 
                 try context.save()
               catch 
                  print("Error: \(error)\nCould not save Core Data context.")
               
               context.reset() // Reset the context to clean up the cache and low the memory footprint.
           

【讨论】:

这是最佳答案,但值未按正确顺序保存。如果顺序很重要,必须将 do catch 块放入 for 循环中。 当值 > 3000 时,此方法不起作用。在 crashlytics -[NSManagedObjectContext save:] + 3304 中给出【参考方案2】:
let employees = NSEntityDescription.insertNewObjectForEntityForName("Employees", inManagedObjectContext: managedObject)
let employees1 = NSEntityDescription.insertNewObjectForEntityForName("Employees", inManagedObjectContext: managedObject)
let employees2 = NSEntityDescription.insertNewObjectForEntityForName("Employees", inManagedObjectContext: managedObject)

employees.setValue("John Doe", forKey: "employeename")
employees.setValue(1, forKey: "id")
employees1.setValue("Jane Doe", forKey: "employeename")
employees1.setValue(2, forKey: "id")
employees2.setValue("Jack Daniels", forKey: "employeename")
employees2.setValue(3, forKey: "id")

do 
    try managedObject.save()
 catch 
    print("problem saving")

【讨论】:

谢谢。由于我要添加多行并且需要使用相同的键,有没有更紧凑的方法可以做到这一点?【参考方案3】:

执行此操作的更紧凑(且可扩展)的方法是将您的姓名数据加载到数组中,然后逐步执行。你真的不想为任意长度的数组硬编码 variable1, variable2

    let employeeNames = ["John Doe", "Jane Doe", "Jack Daniels"]

    for (index, employee) in employeeNames.enumerate()
    
        let employeeEntry = NSEntityDescription.insertNewObjectForEntityForName("Employees", inManagedObjectContext: managedObject)

        employeeEntry.setValue("John Doe", forKey: "employeename")
        employees.setValue(index, forKey: "id")

        do 
            try managedObject.save()
         catch 
            print("problem saving")
        
    

【讨论】:

【参考方案4】:

这可能是基本的,但像我这样的人可以从中受益,这就是为什么发布我的答案。我从 Gurjinder Singh 发布的答案中发现,如果您想一次性保存多个元素,请插入一个唯一的 ID,该 ID 也唯一地代表数据库中的每个值,否则它将添加元素,但所有内容都将是换成单人。例如见下图:

  guard let appDelegegate = UIApplication.shared.delegate as? AppDelegate else
        return
    
    let managedContext = appDelegegate.persistentContainer.viewContext
    let entity = NSEntityDescription.entity(forEntityName: "Employees", in: managedContext)!
    let employeeNames = ["John Doe", "Jane Doe", "Jack Daniels"]
    for index in 0..<employeeNames.count
        let newEmployee = NSManagedObject(entity: entity, insertInto: managedContext)
        newEmployee.setValue(self. employeeNames[index], forKey: "employeename")
    

在这种情况下,数据库中将有三个条目,并且都是相同的。因此,请在每个条目中也插入一些唯一的 id,以便像这样将每个元素与其他元素区分开来。

   for index in 0..<employeeNames.count 
      let newEmployee = NSManagedObject(entity: entity!, insertInto: context)
      newEmployee.setValue(employeeNames[index], forKey: "employeename")
      newEmployee.setValue(index, forKey: "id")
    

是的,别忘了在实体中添加相同的属性;)

【讨论】:

以上是关于如何在 CoreData 中保存多个条目?的主要内容,如果未能解决你的问题,请参考以下文章

如何以一个名称将多个对象保存到 CoreData

更新当前的 CoreData 条目

如何一次将多个关系保存到 CoreData?

如何允许 CoreData 实体列表中的重复条目

如何在 Swift 中的 Core Data 中保存多个项目

如何使用 NSPredicate 通过 CoreData 中的 NSSet 属性的元素过滤对象?