Core Data Trouble - Can't save nor update value correctly

Hello everybody,


I am developing my first app. The layouts are done and everything is working fine. My only problem now is with Core Data. I have a transition fom one Segue to the other and with that I pass a boolean value that tells me what happened before.


The values are behind passed correctly, I debbuged that but the variables I want to update are always wrong and changing, for exemple, from 2 to 14. I only added one.


This is my swift code.


import UIKit
import CoreData

class StartScreenVC: UIViewController {
    
    var guessedNumber: Bool = false
    var gameCompleted: Bool = false
    
    @IBOutlet weak var gamesCompletedLabel: UILabel!
    @IBOutlet weak var numbersGuessedLabel: UILabel!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        let appDelegate = UIApplication.shared.delegate as! AppDelegate
        let context = appDelegate.persistentContainer.viewContext
        
        let entity = NSEntityDescription.entity(forEntityName: "User", in: context)
        let thisUser = NSManagedObject(entity: entity!, insertInto: context)
        
        let request = NSFetchRequest<NSFetchRequestResult>(entityName: "User")
        request.returnsObjectsAsFaults = false
        
        func update() {
            var toDisplayGuessedNumbers: Int!
            var toDisplayCompletedGames: Int!
            
            let request = NSFetchRequest<NSFetchRequestResult>(entityName: "User")
            request.returnsObjectsAsFaults = false
            do {
                let result = try context.fetch(request)
                for data in result as! [NSManagedObject] {
                    toDisplayGuessedNumbers = (data.value(forKey: "numbersGuessed") as! Int)
                    toDisplayCompletedGames = (data.value(forKey: "gamesCompleted") as! Int)
                    
                    if guessedNumber {
                        toDisplayCompletedGames = toDisplayCompletedGames + 1
                        toDisplayGuessedNumbers =  toDisplayGuessedNumbers + 1
                        thisUser.setValue(toDisplayGuessedNumbers, forKey: "numbersGuessed")
                        thisUser.setValue(toDisplayCompletedGames, forKey: "gamesCompleted")
                        try context.save()
                    }
                    else if gameCompleted {
                        toDisplayCompletedGames = toDisplayCompletedGames + 1
                        thisUser.setValue(toDisplayCompletedGames, forKey: "gamesCompleted")
                        try context.save()
                    }
                    gamesCompletedLabel.text! = String(data.value(forKey: "gamesCompleted") as! Int)
                    numbersGuessedLabel.text! = String(data.value(forKey: "numbersGuessed") as! Int)
                }
            } catch {
                print("Failed")
            }
        }
        
        do {
            let result = try context.fetch(request)
            for data in result as! [NSManagedObject] {
                if guessedNumber || gameCompleted {
                    update()
                }
                else {
                    let currentGuessedNumbers = (data.value(forKey: "numbersGuessed") as! Int)
                    let currentGamesCompleted = (data.value(forKey: "gamesCompleted") as! Int)
                    
                    gamesCompletedLabel.text! = String(currentGamesCompleted)
                    numbersGuessedLabel.text! = String(currentGuessedNumbers)
                }
            }
        } catch {
            print("Failed")
        }
    }
    
    @IBAction func showDifficultyPopUp(_ sender: Any) {
        let popOverVC = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "chooseDifficultyVC") as! difficultyPopUp
        self.addChildViewController(popOverVC)
        popOverVC.view.frame = self.view.frame
        self.view.addSubview(popOverVC.view)
        popOverVC.didMove(toParentViewController: self)
    }
}


When the view loads it sets up core data stuff and then goes to line 56, I think. Then, deppending on the guessedNumber and gameCompleted variables I go to the update function. That is where i think the problem is.


I want to update the gamesCompleted and the numbersGuessed values. The app just does weird stuff with the numbers, I cant get it right. Some help would be very nice. 😀


Thank you very much.

Replies

First problem is that you’re creating too many User entities. On line 19 you create a new User entity each time you load that view. Usually, you check to see if there’s a suitable pre-existing User instance before creating a new one.


Second problem is that in lines 57-69 you’re fetching all the User entities and iterating over them, but instead of passing data to update on line 60, your update func is executing another request and iterating over another set of User entities.


Eliminate lines 28-32 and 50-53, and change update to take a parameter named data.