1

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

0 Answers0