Reputation: 143
I'm creating a document based app, using swift / SwiftUI and core data for the first time. My approach for CRUDing works - but it doesn't seem to be "right" somehow. Maybe there is a more elegant way of doing this. In my Document-Class I get my NSManagedObjectContext. Beside this, I define one other environment Object - a Class that keeps my Entities
class MainContent: ObservableObject {
@Published var entity1:[Entity1]! = []
@Published var entity2:[Entity2]! = [] }
These two EnvironmentObjects are available through the whole app now - first my context, second my mainContent.
Whenever I want to add an Object, I call a function and pass in the context and all the data. This did not refresh the actual view (unless I restarted the app), so as a result I needed to return an updated array:
Button(action: {
// Add new - if that fails catch the error
do {
self.mainContent.entity1 = try addEntity1(context: self.context, name: self.textFieldName)
/* ... */
} catch {
/* Errorhandling */
}
} ) {
Text("Add")
}
The according function looks smth like that:
func addEntity1(context:NSManagedObjectContext, name:String) throws -> [Entity1] {
/* ... check if entered data is ok */
let newData = Entity1(context: context)
newData.name = name
// Errorhandling
// if function didn't throw -> update mainContent.Entity1
let rows: [Entity1]!
do {
rows = try fetchEntity1(context: context)
} catch {
/* ... */
}
return rows
}
Is this the best way to solve this? or is there some easier way, that does not need the 2nd EnvironmentObject (so my mainContent) - and by this not passing back the whole data out of my function every time? This solution also came with the downside that Undo/redo does not update views - so maybe I'm just doing smth wrong here.
EDIT
I discovered the @FetchRequest Property to load the data in my view without storing it in between somewhere. This comes with another downside though: Whenever I open a second document, the console outputs a bunch of errors like
2020-08-17 10:10:50.252574+0200 testApp[1282:25685] [error] warning: Multiple NSEntityDescriptions claim the NSManagedObject subclass 'Department' so +entity is unable to disambiguate.
CoreData: warning: Multiple NSEntityDescriptions claim the NSManagedObject subclass 'Department' so +entity is unable to disambiguate.
2020-08-17 10:10:50.252658+0200 testApp[1282:25685] [error] warning: 'Department' (0x60000351ca50) from NSManagedObjectModel (0x60000210def0) claims 'Department'.
CoreData: warning: 'Department' (0x60000350d340) from NSManagedObjectModel (0x60000212e5d0) claims 'Department'.
2020-08-17 10:10:50.252741+0200 testApp[1282:25685] [error] error: +[Department entity] Failed to find a unique match for an NSEntityDescription to a managed object subclass
I found a bunch of solutions to this problem - none of them work though. I made sure the MOC was injected right like suggested here SwiftUI @FetchRequest crashes the app and returns error
I changed the entity module like suggested here Unable to find specific subclass of NSManagedObject
I created an empty data set in the Document-class for new files (read that somewhere - can't find the link anymore)
let isNew = self.fileURL == nil
if isNew {
_ = Department(context: self.managedObjectContext!)
_ = Cue(context: self.managedObjectContext!)
_ = Task(context: self.managedObjectContext!)
}
I made a small example with only a few lines of code and shared it on gitHub here: https://github.com/Duras666/PersonListTest Even this basic small app runs into the same error, as soon as I open a second document
Upvotes: 1
Views: 401