我正在使用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>
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,崩溃似乎就会出现。我不确定这是否对您有帮助。
感谢您的帮助,谢谢。
答案 0 :(得分:0)
好的,因此从lazy
的{{1}}行中删除lazy var persistentContainer: NSPersistentCloudKitContainer = {...}()
有助于我的情况。因为似乎苹果公司在AppDelegate
行中传递了NSManagedObjectModel
的样板代码,并且FetchRequest在该对象被闭包正确实例化之前访问了该对象,因此无法找到{{1} }。从变量中删除let contentView = ContentView().environment(\.managedObjectContext, persistentContainer.viewContext)
会立即执行关闭操作。
希望这对您有所帮助,并能解决您所遇到的问题。
答案 1 :(得分:0)
在选中“核心数据”支持后,尝试从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)")
}
})
}
}
答案 2 :(得分:0)
将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)!
}
}