4thSpace
4thSpace

Reputation: 44312

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

Upvotes: 10

Views: 7864

Answers (4)

Simple Maurya
Simple Maurya

Reputation: 105

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 ;)

Upvotes: 1

Gurjinder Singh
Gurjinder Singh

Reputation: 10299

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

Upvotes: 13

Russell
Russell

Reputation: 5554

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

Upvotes: 2

Yagnesh Dobariya
Yagnesh Dobariya

Reputation: 2251

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

Upvotes: 5

Related Questions