Nspersistentdocument Core Data Tutorial For Mac



The NSPersistentDocument class is a subclass of NSDocument that is designed to easily integrate into the Core Data framework. It provides methods to access a document-wide NSManagedObjectContext object, and provides default implementations of methods to read and write files using the persistence framework. Add a Core Data data model (give it a name of your choice and just click Finish in the 3rd step of the wizard). Double-click on the new data model file to open it with the data model editor. Add an entity called 'Skill' with a string attribute called 'name' and an integer 16 attribute called 'level'. Save the data model.

I'm working on an OSX (Mac OS) document based app with Core Data.

I'm having problems importing in a PrivateContext. Importing in the MainContext works fine, but of course freezes the UI.


The app has a NSPersistentDocument (Document.h and .m).

In this document I have autosavesInPlace enabled (YES).


The Window belonging to the Document is added in makeWindowControllers

- (void)makeWindowControllers {

familyWindowController *myWindow = [[NSStoryboard storyboardWithName:@'Main' bundle:nil] instantiateControllerWithIdentifier:@'Document Window Controller'];

[self addWindowController: myWindow];

myWindow.managedObjectContext = self.managedObjectContext;

Nspersistentdocument Core Data Tutorial For Mac Shortcut

}


The WindowController gets his NSManagedObjectContext (MOC) from self.managedObjectContext.

Nspersistentdocument Core Data Tutorial For Mac Desktop

This Window and MOC are given to childViewControllers, like the sheet I use for the import progress from a file.


The import sheet (ViewController) has a NSWindow property and a MOC property which is set by the prepareForSegue.

Next to the MOC from the Main window I have a PrivateContext (MOC).

It turn out that the originally created MOC is NOT of the NSMainQueueConcurrencyType. This is required is you want to use it with a parentContext.

With this code I change it (maybe this is wrong?).


NSManagedObjectContext *context = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];

context.persistentStoreCoordinator = self.managedObjectContext.persistentStoreCoordinator;

[context setMergePolicy: NSMergeByPropertyStoreTrumpMergePolicy];

_managedObjectContext = context; // _managedObjectContext is the local MOC from the WindowController

Nspersistentdocument Core Data Tutorial For Mac Os


The privateContext is created with this code.
_privateContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];

_privateContext.parentContext = _managedObjectContext;

_privateContext.undoManager = nil;

I parse an XML with Google’s GDataXMLNode.

Core data objects are created with

Person *currentPersonObject = [NSEntityDescription insertNewObjectForEntityForName:@'Person' inManagedObjectContext:_managedObjectContext];

What works:

If I don’t change the MOC to a NSMainQueueConcurrencyType, everything works fine, but I have a frozen UI.

Pro

What don’t work:

- When I make the MOC into a NSMainQueueConcurrencyType, I can import the data, but it doesn’t save to the file. I suspect something is wrong with the persistentStore, but I don’t see what.

- When I use the PrivateContext (thru the Parent) I can get progress in the UI en UI updates, as long *** I don’t move the Window or trigger a Window refresh. I think this is because of the NSTableViews in the Window, which all use Core Data and binding. So when they refresh the view you get Core Data errors (out of bound…). No Idea how to fix this.

Any ideas are welcome.

An example with OSX NSDocument and Core Data would be even better