CoreData和SwiftUI:环境中的上下文未连接到持久性存储协调器 [英] CoreData and SwiftUI: Context in environment is not connected to a persistent store coordinator

查看:158
本文介绍了CoreData和SwiftUI:环境中的上下文未连接到持久性存储协调器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试通过构建一个作业管理应用程序来自学核心数据。我的代码构建良好,并且该应用程序可以正常运行,直到我尝试向列表中添加新任务。我在以下行上收到此错误线程1:EXC_BREAKPOINT(代码= 1,子代码= 0x1c25719e8)在以下行上: ForEach(courses,id:\。自我){当然在中。控制台也有此错误:环境中的上下文未连接到持久性存储协调器:< NSManagedObjectContext:0x2823cb3a0>

I am trying to teach myself Core Data by building a homework managing app. My code builds fine and the app runs okay until I try to add a new assignment to the list. I get this error Thread 1: EXC_BREAKPOINT (code=1, subcode=0x1c25719e8) on the following line: ForEach(courses, id: \.self) { course in. The console also has this error: Context in environment is not connected to a persistent store coordinator: <NSManagedObjectContext: 0x2823cb3a0>.

我对核心数据了解甚少,并且对可能出现的问题不知所措。我已经在数据模型中设置了分配和课程实体,其中Course与分配具有一对多关系。每个作业都将根据特定的课程进行分类。

I know very little about Core Data and am at a loss as to what the issue might be. I have set up "Assignment" and "Course" entities in the data model, where Course has a one-to-many relationship to Assignment. Each assignment will be categorized under a particular course.

这是用于将新作业添加到列表的视图的代码:

This is the code for the view that adds a new assignment to the list:

    struct NewAssignmentView: View {

    @Environment(\.presentationMode) var presentationMode
    @Environment(\.managedObjectContext) var moc
    @FetchRequest(entity: Course.entity(), sortDescriptors: []) var courses: FetchedResults<Course>

    @State var name = ""
    @State var hasDueDate = false
    @State var dueDate = Date()
    @State var course = Course()

    var body: some View {
        NavigationView {
            Form {
                TextField("Assignment Name", text: $name)
                Section {
                    Picker("Course", selection: $course) {
                        ForEach(courses, id: \.self) { course in
                            Text("\(course.name ?? "")").foregroundColor(course.color)
                        }
                    }
                }
                Section {
                    Toggle(isOn: $hasDueDate.animation()) {
                        Text("Due Date")
                    }
                    if hasDueDate {
                        DatePicker(selection: $dueDate, displayedComponents: .date, label: { Text("Set Date:") })
                    }
                }
            }
            .navigationBarTitle("New Assignment", displayMode: .inline)
            .navigationBarItems(leading: Button(action: {
                self.presentationMode.wrappedValue.dismiss()
            }, label: { Text("Cancel") }),
                                trailing: Button(action: {
                                    let newAssignment = Assignment(context: self.moc)
                                    newAssignment.name = self.name
                                    newAssignment.hasDueDate = self.hasDueDate
                                    newAssignment.dueDate = self.dueDate
                                    newAssignment.statusString = Status.incomplete.rawValue
                                    newAssignment.course = self.course
                                    self.presentationMode.wrappedValue.dismiss()
                                }, label: { Text("Add").bold() }))
        }
    }
}

编辑:这是AppDelegate中设置持久性容器的代码:

Here is the code in AppDelegate that sets up the persistent container:

lazy var persistentContainer: NSPersistentCloudKitContainer = {
    let container = NSPersistentCloudKitContainer(name: "test")
    container.loadPersistentStores(completionHandler: { (storeDescription, error) in
        if let error = error as NSError? {
            fatalError("Unresolved error \(error), \(error.userInfo)")
        }
    })
    return container
}()

SceneDelegate中设置环境的代码:

And the code in SceneDelegate that sets up the environment:

    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
    // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
    // If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
    // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).

    // Get the managed object context from the shared persistent container.
    let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext

    // Create the SwiftUI view and set the context as the value for the managedObjectContext environment keyPath.
    // Add `@Environment(\.managedObjectContext)` in the views that will need the context.
    let contentView = ContentView().environment(\.managedObjectContext, context)

    // Use a UIHostingController as window root view controller.
    if let windowScene = scene as? UIWindowScene {
        let window = UIWindow(windowScene: windowScene)
        window.rootViewController = UIHostingController(rootView: contentView)
        self.window = window
        window.makeKeyAndVisible()
    }
}


推荐答案

像您的环境值moc仅自动传递给层次结构中的其他视图。因此,如果您显示工作表或不属于视图层次结构的任何内容,则将失去环境,您将需要将moc传递给新层次结构,就像对ContentView所做的那样。检查以下代码段:

Environment values like your moc are automatically passed only to other views in the hierarchy. So if you show a sheet or anything that is not part of your view hierarchy you'll lose the environment and you will need to pass the moc to the new hierarchy, like you did for ContentView. Check this code snippet:

.sheet(isPresented: self.$showSheet) {
            SheetView()
                .environment(\.managedObjectContext, self.moc)
        }

这篇关于CoreData和SwiftUI:环境中的上下文未连接到持久性存储协调器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆