Search code examples
swiftuicore-data

Error: Thread 1: "executeFetchRequest:error: A fetch request must have an entity."


I'm trying to use CoreData in my Xcode-project (SwiftUI). I've created a Player entity and wanna use it in my View called "YouView". But when I'm trying to fetch the data, I get the error from Title. My app is called Dart Tools. My Application Language is German, so don't worry if you don't understand everything of the ui :).

Thanks for helping!

I already tried the .shared variant - same error

This is my .xcdatamodeld file (called DataModel.xcdatamodeld)

This is the Code of my DataController file:

import Foundation
import CoreData

class DataController: ObservableObject {
    
    let container = NSPersistentContainer(name: "DataModel")
    
    init()  {
        container.loadPersistentStores { desc, error in
            if let  error = error {
                print("Daten wurden nicht geladen: \(error.localizedDescription)")
            }
        }
    }
    
    func save(context: NSManagedObjectContext) {
        do {
            try context.save()
            print("Daten wurden gespiechert!")
        } catch {
            print("Daten konnten nicht gespeichert werden.")
        }
    }
    
    func addPlayer(name: String, isUser: Bool, context: NSManagedObjectContext) {
        let player = Player(context: context)
        player.id = UUID()
        player.name = name
        player.isUser = isUser
        
        save(context: context)
    }
    
    func editPlayerName(player: Player, name: String, context: NSManagedObjectContext) {
        player.name = name
        
        save(context: context)
    }
}

Here is my DartToolsApp.swift file:

import SwiftUI

//The error is here:
@main

struct DartToolsApp: App {
    
    @StateObject private var userDefaults = UserDefaults()
    @StateObject private var dataController = DataController()
    
    var body: some Scene {
        WindowGroup {
            ContentView()
                .environment(\.managedObjectContext, DataController().container.viewContext)
                .environmentObject(UserDefaults())
        }
    }
}

This is the file where I want to use the Data:

Btw, this view is a piece of a TabView.

import SwiftUI
import CoreData

struct YouView: View {
    
    @EnvironmentObject var userDefaults: UserDefaults
// I guess the error is because of this line:
    @FetchRequest(sortDescriptors: []) var players: FetchedResults<Player>
    
    @Environment(\.managedObjectContext) var managedObjectContext
    
    var body: some View {
        NavigationStack {
            Form {
                
            }
            .navigationTitle("\(findUser()) (Du)")
        }
    }
    
    func findUser() -> String {
        if let index = players.firstIndex(where: { $0.isUser }) {
            let output = players[index].name!
            return output
        }
        else {
            return ""
        }
    }
}

This is the code to create the user:

DataController().addPlayer(name: nameText, isUser: true, context: managedObjectContext)

Wow, that was a lot of code. I hope you can help me!


Solution

  • You are creating new instances of DataController everywhere which is a problem in itself but what think causes your particular error is when you assign the \.managedObjectContext environment variable.

    So instead of creating a new instance you should use your @StateObject instance instead.

    So change this in the App code

    var body: some Scene {
        WindowGroup {
            ContentView()
                .environment(\.managedObjectContext, dataController.container.viewContext)
        }
    }