Xcode 12.1 中的 CoreData 错误

CoreData bug in Xcode 12.1

我正在研究 Paul Hudson 的 SwiftUI 100 天,并且在项目 11 中遇到了一个令人沮丧的 CoreData 问题。这是 Paul 代码的直接提升,在他的视频中编译和运行良好。 Bookworm.xcdatamodeld 有一个名为 Student 的实体,它有两个属性:一个名为 id 的 UUID 和一个名为 name 的字符串。

它编译得很好,但是 运行 它导致 ForEach 崩溃,'students' 带有红色下划线。控制台中弹出的错误消息显示:

2020-10-31 12:13:47.934507-0400 书虫[614:7766183] [错误] 错误:任何模型中的 NSEntityDescriptions 都没有声明 NSManagedObject 子类 'Bookworm.Student' 所以 +entity 很混乱。你载入你的 NSManagedObjectModel 了吗? CoreData:错误:任何模型中都没有 NSEntityDescriptions 声明 NSManagedObject 子类 'Bookworm.Student' 所以 +entity 很困惑。你载入你的 NSManagedObjectModel 了吗? 2020-10-31 12:13:47.934651-0400 Bookworm[614:7766183] [error] error: +[Bookworm.Student entity] 未能找到 NSEntityDescription 与托管对象子类的唯一匹配项 CoreData: error: +[Bookworm.Student entity] 未能找到 NSEntityDescription 与托管对象子类的唯一匹配项 2020-10-31 12:13:47.953419-0400 Bookworm[614:7766183] [SwiftUI] 环境中的上下文未连接到持久存储协调器:

我搜索了大量内容,并尝试了我发现的所有推荐解决方案,包括:简单地关闭并重新打开 Xcode(第 1 步),清理项目然后重复第 1 步,并删除所有派生的数据并重复步骤 1。我已验证在模块的检查器中选择了当前产品模块,并且 Codegen 已选择 Class 定义。

import SwiftUI
import CoreData

struct ContentView: View {

    @Environment(\.managedObjectContext) var moc
    @FetchRequest(entity: Student.entity(), sortDescriptors: []) var students: FetchedResults<Student>

    var body: some View {
        VStack {
            List {
                ForEach(students, id: \.id) { student in
                    Text(student.name ?? "Unknown")
                }
            }
        }
    }
 }

如果您正在使用 SwiftUI 生命周期,您应该在父视图(或应用程序)中初始化 NSPersistentContainer 并将 managedObjectContext 导入到环境中。

在你的情况下,它可能是这样的:

import SwiftUI
import CoreData

@main
struct coreDataParadigmApp: App {
    let persistenceController = PersistenceController.shared
    var body: some Scene {
        WindowGroup {
            ContentView()
                .environment(\.managedObjectContext, persistenceController.container.viewContext)
        }
    }
}


struct ContentView: View {
    @FetchRequest(entity: Student.entity(), sortDescriptors: []) var students: FetchedResults<Student>
    var body: some View {
        VStack {
            List {
                ForEach(students, id: \.id) { student in
                    Text(student.name ?? "Unknown")
                }
            }
        }
    }
 }

// DONT FORGET TO CHANGE THE NAME OF YOUR FILE
struct PersistenceController {
    static let shared = PersistenceController()

    let container: NSPersistentContainer

    init() {
        container = NSPersistentContainer(name: "coreDataNameOfFile")

        container.loadPersistentStores(completionHandler: { (storeDescription, error) in
            if let error = error as NSError? {
                fatalError("Unresolved error \(error), \(error.userInfo)")
            }
        })
    }
}