CoreData and SwiftUI: Context in environment is not connected to a persistent store coordinator

前端 未结 2 1273
执念已碎
执念已碎 2020-12-03 03:38

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 t

相关标签:
2条回答
  • 2020-12-03 03:58

    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)
            }
    
    0 讨论(0)
  • 2020-12-03 04:04

    You're not actually saving the context. You should be executing the following:

    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
    
    do {
        try self.moc.save()
    } catch {
        print(error)
    }
    

    Also your @FetchRequest(...) could look like this:

    @FetchRequest(fetchRequest: CourseItem.getCourseItems()) var courses: FetchedResults<CourseItem>
    

    You can modify your CourseItem class to handle the sortDescriptors like the following:

    public class CourseItem: NSManagedObject, Identifiable {
        @NSManaged public var name: String?
        @NSManaged public var dueDate: Date?
        // ...etc
    }
    
    extension CourseItem {
        static func getCourseItems() -> NSFetchRequest<CourseItem> {
            let request: NSFetchRequest<CourseItem> = CourseItem.fetchRequest() as! NSFetchRequest<CourseItem>
    
            let sortDescriptor = NSSortDescriptor(key: "dueDate", ascending: true)
    
            request.sortDescriptors = [sortDescriptor]
    
            return request
        }
    }
    

    Then you would modify your ForEach(...) like the following and can also handle the deletion of items quite easily as well:

    ForEach(self.courses) { course in
        // ...
    }.onDelete { indexSet in
        let deleteItem = self.courses[indexSet.first!]
        self.moc.delete(deleteItem)
    
        do {
            try self.moc.save()
        } catch {
            print(error)
        }
    }
    

    One thing you want to ensure is that the "Class Name" is set to "CourseItem", which matches the CourseItem class we created earlier.

    Simply click ENTITIES in your .xcdatamodeId file and set everything to the following (including Module to "Current Product Module" and Codegen to "Manual/None"):

    0 讨论(0)
提交回复
热议问题