Andrea Toso Andrea Toso - 1 month ago 5
Swift Question

Core Data is saving only last item

I have a

function
with a
entity
and a
item
,and append the value in an
array
, but it adds only the last item and I think it's because every time I iterate through the array I append the value in the same
instance
.I can't figure out why.
My function:

func saveItem(itemToSave: String, key: String){
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let managedContext = appDelegate.managedObjectContext

let entity = NSEntityDescription.entity(forEntityName: "Recipe", in: managedContext)
let item = NSManagedObject(entity: entity!, insertInto: managedContext)
item.setValue(itemToSave, forKey: key)
do{
try managedContext.save()
recipes.append(item)
}catch{
print("\(error)")
}}


How I call the function:

if let title = self.newRecipeView.titleTextField.text{
saveItem(itemToSave: title, key: "title")
}


First image: https://i.stack.imgur.com/UrLbi.png
Second image: https://i.stack.imgur.com/XjiEP.png

The action when I click the button:

UIView.animate(withDuration: 0.7, delay: 0, options: .curveEaseOut, animations: {
clearView.alpha = 1
self.contentView.isUserInteractionEnabled = false
activityIndicator.startAnimating()
}, completion: { (true) in

if let title = self.newRecipeView.titleTextField.text{
saveItem(itemToSave: title, key: "title")
}

if let category = UserDefaults.standard.object(forKey: "category") as! String?{
saveItem(itemToSave: category, key: "category")
}

if let rating = self.newRecipeView.ratingTextField.text{
saveItem(itemToSave: rating, key: "rating")
}

if let time = self.newRecipeView.timeTextField.text{
saveItem(itemToSave: time, key: "time")
}

if let directions = self.newRecipeView.directionsTextField.text{
saveItem(itemToSave: directions, key: "directions")
}

fetchData()
print(recipes)


activityIndicator.stopAnimating()
_ = self.navigationController?.popToRootViewController(animated: true)
})


Method which save data:

func saveItem(itemToSave: String, key: String){
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let managedContext = appDelegate.managedObjectContext

let entity = NSEntityDescription.entity(forEntityName: "Recipe", in: managedContext)
let item = NSManagedObject(entity: entity!, insertInto: managedContext)
item.setValue(itemToSave, forKey: key)
do{
try managedContext.save()
recipes.append(item)
}catch{
print("\(error)")
}


}

Method which fetch data:

func fetchData(){
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let managedContext = appDelegate.managedObjectContext

let fetchRequest:NSFetchRequest<NSFetchRequestResult> = NSFetchRequest(entityName: "Recipe")
do{
let results = try managedContext.fetch(fetchRequest)
recipes = results as! [NSManagedObject]
}catch{
print("\(error)")
}


}

Answer

Your problem is that you create a new Recipe for every item.

You need to change your function to the following:

func saveItem(title: String, rating: String, category: String, time: String, directions: String){
    let appDelegate = UIApplication.shared.delegate as! AppDelegate
    let managedContext = appDelegate.managedObjectContext

    let entity = NSEntityDescription.entity(forEntityName: "Recipe", in: managedContext)
    let item = NSManagedObject(entity: entity!, insertInto: managedContext)

    recipe.setValue(title, forKey: "title")
    recipe.setValue(rating, forKey: "rating")
    recipe.setValue(category, forKey: "category")
    recipe.setValue(time, forKey: "time")
    recipe.setValue(directions, forKey: "directions")

    do{
        try managedContext.save()
        recipes.append(recipe)
    }catch{
        print("\(error)")
    }
}

And then call it by:

saveItem(title: self.newRecipeView.titleTextField.text, rating: self.newRecipeView.ratingTextField.text, category: (UserDefaults.standard.object(forKey: "category") as! String?), time: self.newRecipeView.timeTextField.text, directions: self.newRecipeView.directionsTextField.text)
Comments