简体   繁体   中英

How to save multiple entries in CoreData?

I have the following code that executes without error. The problem is it only saves the last entry ("Jack Daniels", 3). How do change this so it will save all three entries?

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")
}

Swift 4.1. You don't need to put save code in for loop. Just insert all enteries then do save them in one go.

 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.
           }
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")
}

A more compact way (and expandable) to do this would be to load your name data into an array, and step through that. You don't really want to be hard-coding variable1, variable2 for arrays of arbitrary length

    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")
        }
    }

It may be basic, but someone like me could be benefitted from this, that's why posting my answer. I have found from answer posted by Gurjinder Singh that if you want to save multiple elements in one go, please insert a unique id also which uniquely reperesent each value in database otherwise it will add element but all will be replaced by single one. For example see below:

  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")
    }

In this scenario, in database there will be three entries and all are same. So please insert some unique id also with each entry to distinguish every element from others like this.

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

And yes don't forget to add same attribute in entity ;)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM