Re: Create and save a NSPersistentDocument from scratch
Re: Create and save a NSPersistentDocument from scratch
- Subject: Re: Create and save a NSPersistentDocument from scratch
- From: Quincey Morris <email@hidden>
- Date: Wed, 11 Nov 2009 11:15:54 -0800
On Nov 11, 2009, at 10:15, Eric Morand wrote:
I don't want my user to work with a non-saved document. Ever. For a
good reason : since you need a saved document to use the
mergeChangesFromContextDidSaveNotification method from
NSManagedObjectContext, I don't have other choice than have my user
always work with a saved document. That's unfortunately the only
solution I've found to be able to use
mergeChangesFromContextDidSaveNotification and conform to the
"NSManagedObjectContrext is a scratchpad" concept.
Your reason is good, but I think the approach is poor. I faced the
same problem a while back (I couldn't use a new document because the
initial data was far too large to fit in memory all at once, and
obviously it couldn't be faulted out to the store if the document had
never been saved), and cobbled together a solution out of various
pieces of sample code from the documentation. This solution bypasses
all the document handling until after the initial store is created,
avoiding the need to hack around the built-in document behavior.
Here's the essence of it, assuming you've run your save panel to get
the URL of the file you want to create:
// Create an empty document persistent store and return its managed
object context
+ (NSManagedObjectContext*) managedObjectContextForNewStoreWithURL:
(NSURL*) storeURL error: (NSError**) outError {
NSString* storePath = storeURL.path;
// Check that the file doesn't already exist
if ([[NSFileManager defaultManager] fileExistsAtPath: storePath])
{ // can be done with the URL directly, in 10.6
// Handle the error
return nil;
}
// Create the file and managed object context
NSManagedObjectContext* result = [self
managedObjectContextForStoreURL: storeURL];
if (!result) {
// Handle the error
return nil;
}
return result;
}
// Create a managed object context for a store, creating the store if
it does not exist
+ (NSManagedObjectContext*) managedObjectContextForStoreURL: (NSURL*)
storeURL {
// Find the document's model
NSManagedObjectModel* model = [NSManagedObjectModel
mergedModelFromBundles: nil];
if (!model)
return nil;
// Create a persistent store
NSPersistentStoreCoordinator* psc = [[NSPersistentStoreCoordinator
alloc] initWithManagedObjectModel: model];
if (!psc)
return nil;
NSError* error;
NSPersistentStore* store = [psc addPersistentStoreWithType:
NSSQLiteStoreType
configuration: nil
URL: storeURL
options: nil
error: &error];
if (!store)
return nil;
// Create a managed object context for the store
NSManagedObjectContext* managedContext = [[NSManagedObjectContext
alloc] init];
if (!managedContext)
return nil;
managedContext.persistentStoreCoordinator = psc;
managedContext.undoManager = nil;
return managedContext;
}
The point of returning a managed object context for the new file is to
allow you to prefill the store with initial data. (Call the moc's
'save:' afterwards, of course.) When you're done setting up the file,
call NSDocumentController's
'openDocumentWithContentsOfURL:display:error:' method to open the
document.
But I don't know what is the file type of my document. I've searched
everywhere in the plist and I didn't find any mention of "file type".
It's normally set in the target properties (Get Info on the target, go
to the Properties tab, create a file type by clicking the "+" button).
I'd like to have the save panel open as a sheet, not a modal window.
And the standard behavior open a modal window. Is there a way to
customize this ?
Not that I know of, directly. But if you use the above technique, you
can run the save panel as a sheet, of course.
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden