I am making simple app, that tracks calories. It stores data in simple CoreData model. This is my code responsible for creating the data model.
It's simple and it's based on the code generated by Xcode.
import Foundation
import CoreData
class PersistenceController: ObservableObject {
static let shared = PersistenceController()
static var preview: PersistenceController = {
let result = PersistenceController(inMemory: true)
let viewContext = result.container.viewContext
do {
try viewContext.save()
} catch {
let nsError = error as NSError
fatalError("Unresolved error \(nsError), \(nsError.userInfo)")
}
return result
}()
let container: NSPersistentContainer
init(inMemory: Bool = false) {
container = NSPersistentContainer(name: "FoodModel")
if inMemory {
container.persistentStoreDescriptions.first!.url = URL(fileURLWithPath: "/dev/null")
}
container.loadPersistentStores(completionHandler: { (storeDescription, error) in
if let error = error as NSError? {
fatalError("Unresolved error \(error), \(error.userInfo)")
}
})
container.viewContext.automaticallyMergesChangesFromParent = true
}
func save(context: NSManagedObjectContext) {
do {
try context.save()
print("Data has been saved successfully.")
} catch {
// Handle errors in our database
let nsError = error as NSError
fatalError("Unresolved error \(nsError), \(nsError.userInfo)")
}
}
func addFood(name: String, calories: Double, context: NSManagedObjectContext) {
let food = Food(context: context)
food.id = UUID()
food.date = Date()
food.name = name
food.calories = calories
save(context: context)
}
func editFood(food: Food, name: String, calories: Double, context: NSManagedObjectContext) {
food.date = Date()
food.name = name
food.calories = calories
save(context: context)
}
}
While trying to add a meal I get this warning from CoreData:
2022-09-06 17:52:24.248483+0200 TrackCalories[67203:10277525] [error] warning: Multiple NSEntityDescriptions claim the NSManagedObject subclass 'TrackCalories.Food' so +entity is unable to disambiguate.
The warning finally results with error:
CoreData: error: +[TrackCalories.Food entity] Failed to find a unique match for an NSEntityDescription to a managed object subclass
Of course apart from the warning and CoreData error my implementation is working and data are correctly saved.
The error and warning only shows up when I try to add new meal.
Worth mentioning is, that the warning and error don't occur when I'm modifying existing entry or deleting it.
So the above functions: addFood and save are responsible for adding and saving the data.
Here's the code, that is supposed to invoke above functions:
struct AddFoodView: View {
@Environment(\.managedObjectContext) var managedObjContext
@Environment(\.dismiss) var dismiss
@State private var name = ""
@State private var calories: Double = 0
var body: some View {
Form {
Section() {
TextField("What have you eaten?", text: $name)
VStack {
Text("Calories: \(Int(calories))")
Slider(value: $calories, in: 0...2000, step: 10)
}
.padding()
HStack {
Spacer()
Button("Add meal") {
PersistenceController().addFood(
name: name,
calories: calories,
context: managedObjContext)
dismiss()
}
Spacer()
}
}
}
}
}
struct AddFoodView_Previews: PreviewProvider {
static var previews: some View {
AddFoodView()
}
}
Thanks to @TomHarrington question is now solved. All credit goes to him.
I've been creating new instance of PersistanceController every time I was adding new meal to the CoreData.
The solution is to access the instance through immutable variable static let shared.
The working code in AddFoodView is then:
PersistenceController.shared.addFood(
name: name,
calories: calories,
context: managedObjContext)
dismiss()
}
