I'm trying to programatically set the initial file url (path,
filename) of an Core Data NSPersistentDocument, or if that is not
possible, at least populate the Save panel with an initial filename.

This is more an NSDocument / UI problem. Pushing this down into the model layer will make Core Data unhappy, as you've discovered.

Do you just want to populate the initial Save dialog ? You could probably just stash the desired URL as an ivar on your document subclass and customize the save dialog.

At first, I was using -[NSDocument
saveToURL:ofType:forSaveOperation:error:].  That worked fine until I
switched from XML to SQLite store, whereupon I began getting "Could
not merge changes" errors when saving [1].

It works for atomic stores because they've cached the entire file in memory, and will overwrite everything on each save. For a store doing incremental operations like SQLite, this fails. The original, or a copy, needs to exist at the destination. Basically, the SQLite store is just fetching and saving deltas. Applying deltas over an empty new file, or some random file, just doesn't work.

Then, I tried to implement -prepareSavePanel: and in there to
setFileURL: if it is found to be nil, as it is for a new document.
But this results in a "nil is not a valid persistent store" being
logged upon saving. [1]

The Core Data layer does not accept nil as a valid persistent URL. We can't save or load stuff from nil. Setting the URL for a persistent store only changes how we refer to the store. The exact same original file MUST exist at the new URL location. Basically setting the URL tells Core Data to update it's path because the file moved out from underneath us.

Then, I tried removing the old persistent store with
removePersistentStore:error: and adding a new one with
addPersistentStoreWithType:configuration:nilURL:options:error:.  But
that results upon saving in errors such as "The NSManagedObject with
ID:0x16d22cb0 <x-coredata://...> has been invalidated".


If you remove a store, all the managed objects from that store are invalidated. Yanking the store out of the stack makes everything from it poisoned fruit, so to speak. Your code still has references to managed objects from the removed store, and when you use them they fail this way.

[1] In the error's userInfo, in the the 'conflictList', I see that the
newVersion is 0 but the old version is 1.  That seems kind of weird
but I'm just guessing...

The versions are always positive integers. 0 means it was deleted. The "new" version is non-existence.

What is the correct approach to do programatically set the file URL of an NSPersistentDocument?

You need to actually have a document before you can change the URL. If you want to move the document, you can move the file and then call setURL. If you want to make the default URL appear to be something particular for an unsaved document, I would recommend doing that as a UI artifact outside of Core Data.

Probably worth a bug.

- Ben

_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to