SwiftUI获取请求错误:'提取请求必须有实体'

mwg9r5ms  于 2022-12-03  发布在  Swift
关注(0)|答案(4)|浏览(158)

我正在使用SwiftUI和CoreData构建一个具有SwiftUI应用程序生命周期的小型应用程序(无场景或应用程序委托)。在运行+构建应用程序时,我收到以下错误:

'executeFetchRequest:error: A fetch request must have an entity.'

我已检查/验证/重新检查以下内容:

  • 我的[app name].xcdatamodeld文件名与传递到NSPersistentContainer NSPersistentCloudKitContainer(name: [app name])的文件名相同
  • 实体的名称Car正是我传递给FetchRequest的名称
@FetchRequest(entity: Car.entity(), sortDescriptors: []) var car: FetchedResults<Car>
  • 我为实体Codegen选择了Manual/None,生成的类为
public class Car: NSManagedObject {}

Car上的分机号为Identifiable
这是我的整个视图结构,它应该(据我的理解)将环境传递给它的所有“子”视图。

struct AppView: View {
    
    @Environment(\.managedObjectContext) var moc
    @FetchRequest(entity: Car.entity(), sortDescriptors: []) var car: FetchedResults<Car>
    
    var body: some View {
        List {
            ForEach(car, id:\.self) { item in
                RootView(carData: item)
                    .environment(\.managedObjectContext, self.moc)
            }
        }
    }
}

和my @main结构

@main
struct AutoMateApp: App {
    
    @StateObject var coreData = PersistentCloudKitContainer()
    
    let persistence = PersistentCloudKitContainer()
    
    var body: some Scene {
        WindowGroup {
            AppView()
                .environment(\.managedObjectContext, coreData.persistentContainer.viewContext)
        }
    }
}

当我使用调试器单步调试时,似乎在返回WindowGroup后出现了崩溃。我不确定这是否是有用的信息。
我很感激你的帮助,谢谢。

flseospp

flseospp1#

好的,在我的例子中,从AppDelegate中的lazy var persistentContainer: NSPersistentCloudKitContainer = {...}()行中删除lazy很有帮助。因为苹果的样板代码似乎在let contentView = ContentView().environment(\.managedObjectContext, persistentContainer.viewContext)行中传递了NSManagedObjectModel,FetchRequest在闭包正确示例化之前访问了该对象,因此无法找到NSManagedObject subclass。从变量中删除lazy会立即执行闭包。
希望这仍然对你有帮助,并在你的情况下解决问题。

628mspwn

628mspwn2#

选中Core Data支持后,尝试SwiftUI应用程序项目模板中的代码:

我的应用程序.swift

import SwiftUI

@main
struct MyApp: App {
    let persistenceController = PersistenceController.shared

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

"坚持,迅速"

import CoreData

struct PersistenceController {
    static let shared = PersistenceController()

    static var preview: PersistenceController = {
        let result = PersistenceController(inMemory: true)
        let viewContext = result.container.viewContext
        for _ in 0..<10 {
            let newItem = Item(context: viewContext)
            newItem.timestamp = Date()
        }
        do {
            try viewContext.save()
        } catch {
            // Replace this implementation with code to handle the error appropriately.
            // fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
            let nsError = error as NSError
            fatalError("Unresolved error \(nsError), \(nsError.userInfo)")
        }
        return result
    }()

    let container: NSPersistentContainer

    init(inMemory: Bool = false) {
        container = NSPersistentContainer(name: "MyApp")
        if inMemory {
            container.persistentStoreDescriptions.first!.url = URL(fileURLWithPath: "/dev/null")
        }
        container.loadPersistentStores(completionHandler: { (storeDescription, error) in
            if let error = error as NSError? {
                // Replace this implementation with code to handle the error appropriately.
                // fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.

                /*
                Typical reasons for an error here include:
                * The parent directory does not exist, cannot be created, or disallows writing.
                * The persistent store is not accessible, due to permissions or data protection when the device is locked.
                * The device is out of space.
                * The store could not be migrated to the current model version.
                Check the error message to determine what the actual problem was.
                */
                fatalError("Unresolved error \(error), \(error.userInfo)")
            }
        })
    }
}
deikduxw

deikduxw3#

Car.entity()替换为静态NSEntityDescription。
这些例子

struct AppView: View {
    
    @Environment(\.managedObjectContext) var moc
    @FetchRequest(entity: AppView_Previews.entity, sortDescriptors: []) var car: FetchedResults<Car>
    
    var body: some View {
        List {
            ForEach(car, id:\.self) { item in
                RootView(carData: item)
                    .environment(\.managedObjectContext, self.moc)
            }
        }
    }
}

struct AppView_Previews: PreviewProvider {
    static var entity: NSEntityDescription {
        return NSEntityDescription.entity(forEntityName: "Car", in: yourViewContext)!
    }
}
cngwdvgl

cngwdvgl4#

我今天遇到了这个问题,我认为问题是在声明和排序的时候出现的。从获取请求中删除实体(这可能允许它在生命周期的稍后阶段通过类型推断来做事情)就解决了这个问题:

@FetchRequest(sortDescriptors: [...], predicate: ...) 
private var things: FetchedResults<Thing>

在设置预览时,可能会在创建和注入环境上下文之前计算Car.entity()

相关问题