Eddie Teixeira
Eddie Teixeira

Reputation: 342

Core Data save function inserting NULL values when trying to update

I'm making this app, and there's this section that basically saves and/or updates a player's score. Thing is that when the player doesn't exist yet, everything works just fine. But when I try to update a player's score by changing it while it is pulled down into a NSManagedObject and then saved again on Core Data, for some reason, for each updated record, a new one with NULL values is being created. I'm trying to analyze my code but no success so far. Has anyone any clue? Thanks in advance. There's the function for saving/updating:

func save(player:Player){

    //this var will hold the fetched data from Core Data
    var people : [NSManagedObject] = []

    //tell whether data was fetched from Core Data or not
    var hasPlayers = false

    guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else{
        return
    }

    let managedContext = appDelegate.persistentContainer.viewContext

    let fetchRequest =
        NSFetchRequest<NSManagedObject>(entityName: "Person")

    //filter for fetchRequest
    let predicate = NSPredicate(format: "name = %@", player.name)

    fetchRequest.predicate = predicate

    do {
        people = try managedContext.fetch(fetchRequest)
    } catch let error as NSError {
        print("Could not fetch. \(error), \(error.userInfo)")
    }

    let entity = NSEntityDescription.entity(forEntityName: "Person", in: managedContext)!

    let person = NSManagedObject(entity: entity, insertInto: managedContext)

    //check is data was fetched
    if !people.isEmpty{
        hasPlayers = true

    }


    if !hasPlayers{
        //create player in Core Data if it doesn't exist yet
        person.setValue(player.name, forKey: "name")

        person.setValue(player.score.total, forKey: "score")
    }else{
        //update player score if player already exist
        for p:NSManagedObject in people{
            if p.value(forKey: "name") as! String == player.name{
                p.setValue(player.score.total, forKey: "score")
                print("Updated: Name:\(p.value(forKey: "name") as! String) Score:\(p.value(forKey: "score") as! Int)")
            }
        }
    }


    do {
        try managedContext.save()
    } catch let error as NSError {
        print("Could not save. \(error), \(error.userInfo)")
    }

}

Upvotes: 0

Views: 1455

Answers (1)

Jon Rose
Jon Rose

Reputation: 8563

You are creating a new entity every time, even if one already exists. move the line let person = NSManagedObject(entity: entity, insertInto: managedContext) to inside if !hasPlayers and only create it the person when you don't already have one.

Upvotes: 3

Related Questions