Search code examples
swiftcore-data

Could not save data in CoreData swift


I am trying to save data in CoreData. When the app is running everything is ok. I receive info that data is saved and receive messages that it is fetching correct. But when I close the app data just disappeared somewhere.

When I created the project I do not check Core Data, so I added xcdatamodel, import CoreData everywhere, updated AppDelegate with the correct NSPersistentContainer name (the name is name of my xcdatamodel) also in Project-General-Frameworks added CoreData.framework.

Here is part of saving, fetching, and deleting data. The file is separate from VC. I do not receive any type of errors.

In my VC I just call savedata(), to save the data. It works before the app is closed.

import UIKit
import CoreData

var cgsTeams = [TeamsCoreData]()

func savedata() {
        saveTeams { (complete) in
            if complete {print("TeamsSaved")}
        }
}

func saveTeams(completion: (_ finished: Bool) -> ()) {
    guard let managedContext = appDelegate?.persistentContainer.viewContext else {return}
    let privateManagedContext = NSManagedObjectContext(concurrencyType: .privateQueueConcurrencyType)
    privateManagedContext.parent = managedContext
    
    
    
    for team in teams {
        let teamsCoreData = TeamsCoreData(context: privateManagedContext)
        teamsCoreData.team = team.name
        teamsCoreData.score = Int32(team.score)
        teamsCoreData.number = Int32(team.number)
        
        do{
            try privateManagedContext.save()
            debugPrint("Succesfully saved teamsCoreData")
            completion(true)
        } catch{
            debugPrint("Could not save - \(error)")
            completion(false)
        }
    }
}

func fetchTeams(completion: (_ complete: Bool) -> ()) {
    guard let managedContext = appDelegate?.persistentContainer.viewContext else { return }

    let fetchRequest = NSFetchRequest<TeamsCoreData>(entityName: "TeamsCoreData")

    do {
        cgsTeams = try managedContext.fetch(fetchRequest)
        print("cgsGameRules fetched")
        teams = [team]()
        for cgsTeam in cgsTeams {
            print("team - \(cgsTeam.team!) added")
            teams.append(team(name:cgsTeam.team!, number: Int(cgsTeam.number), score: Int(cgsTeam.score)))
        }
        if cgsTeams.count > 1{completion(true)} else {completion (false); print("No teams")}
    } catch {
        debugPrint("Could not fetch: \(error.localizedDescription)")
        completion(false)
    }
    
    
}

func deleteTeams(){
    guard let managedContext = appDelegate?.persistentContainer.viewContext else { return }
    let fetchRequest = NSFetchRequest<TeamsCoreData>(entityName: "TeamsCoreData")
    
    let objects = try! managedContext.fetch(fetchRequest)
    for obj in objects {
        managedContext.delete(obj)
    }

    do {
        try managedContext.save()
    } catch {
        print("error on delete Team")
    }
}

Solution

  • When you save changes in Core Data, the context saves only to its parent context. If it doesn't have a parent context, it saves changes to the persistent store file. You're saving changes on privateManagedObjectContext, which is a child context of viewContext. But you're never saving changes on viewContext. So your child context is telling the parent context about the changes, but the parent never saves those changes anywhere.

    You need to either (a) save changes on viewContext, or (b) make privateManagedObjectContext its own stand-alone context, not a child context.