问题描述
我正在使用SwiftUI和CoreData构建一个小型应用程序,并具有SwiftUI应用程序生命周期(无场景或应用程序委托)。运行并构建我的应用程序时出现以下错误:
'executeFetchRequest:error: A fetch request must have an entity.'
我已经检查/验证/重新检查了以下内容:
- 我的
[app name].xcdatamodeld
文件名与传递给NSPersistentContainerNSPersistentCloudKitContainer(name: [app name])
的文件名相同 - 实体的名称
Car
正是我传递给FetchRequest的名称
@FetchRequest(entity: Car.entity(),sortDescriptors: []) var car: FetchedResults<Car>
- 我正在为实体Codegen选择“手动/无”,并且生成的类是
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)
}
}
}
}
和我的@main结构
@main
struct AutoMateApp: App {
@StateObject var coreData = PersistentCloudKitContainer()
let persistence = PersistentCloudKitContainer()
var body: some Scene {
WindowGroup {
AppView()
.environment(\.managedObjectContext,coreData.persistentContainer.viewContext)
}
}
}
当我逐步使用调试器时,一旦返回WindowGroup,崩溃似乎就会出现。我不确定这是否对您有帮助。
感谢您的帮助,谢谢。
解决方法
好的,因此从lazy
的{{1}}行中删除lazy var persistentContainer: NSPersistentCloudKitContainer = {...}()
有助于我的情况。因为似乎苹果公司在AppDelegate
行中传递了NSManagedObjectModel
的样板代码,并且FetchRequest在该对象被闭包正确实例化之前访问了该对象,因此无法找到{{1} }。从变量中删除let contentView = ContentView().environment(\.managedObjectContext,persistentContainer.viewContext)
会立即执行关闭操作。
希望这对您有所帮助,并能解决您所遇到的问题。
,在选中“核心数据”支持后,尝试从SwiftUI应用项目模板中获取代码:
MyApp.swift
import SwiftUI
@main
struct MyApp: App {
let persistenceController = PersistenceController.shared
var body: some Scene {
WindowGroup {
ContentView()
.environment(\.managedObjectContext,persistenceController.container.viewContext)
}
}
}
Persistance.swift
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)")
}
})
}
}
,
将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)!
}
}