0

In my subclass of NSPersistentDocument, I overwrite this function:

func writeToURL(absoluteURL: NSURL, ofType typeName: FileType, 
               forSaveOperation saveOperation: NSSaveOperationType, 
               originalContentsURL absoluteOriginalContentsURL: NSURL?) throws

I read the documents, headers files and whatever I could find online. But I don't fully understand what I am supposed to do here. I know thus far I get a lot of crashes and odd behaviour. I think it has to do with the NSPersistentDocument using the wrong persistent store file.

So I do this to see what happens:

  1. start the app,
  2. open a new document,
  3. wait for it to do an autosave (AutosaveElsewhereOperation), then
  4. duplicate the document, and
  5. wait for both documents to autosave.

At the start of the function I print the various URL's.

Swift.print("\n\nsaving \(saveOperation.description) \nfile:____\(self.fileURL) \nstore:___\(self.persistentStore?.URL) @ \n__________________\(absoluteURL) | \norginal: \(absoluteOriginalContentsURL)")

This code is used for autosaving.

case .AutosaveElsewhereOperation:       
if self.persistentStore == nil //new store
{
    let type = self.storageStoreTypeForFileType(typeName)
    self.persistentStore = try self.addPersistentStore(type, atLocation: absoluteURL)
}           
try self.save()

I get the following output

> did init nil => a new file was init'ed
> 
> saving auto elsewhere  => the file was autosaved for the first time
> file:____nil  
> store:___nil 
> _________.../Unsaved_Document.sqlite
> original:.../Unsaved_Document.sqlite
>
> did init nil  => the duplicate file was init'ed
> 
> saving auto elsewhere   => a file was autosaved
> file:____nil 
> store:.../Unsaved_Document.sqlite
> ______.../Unsaved_Document 2.sqlite
> orginal:./Unsaved_Document 2.
> 
> saving auto elsewhere   => a file was autosaved
> file:____nil 
> store:___.../Unsaved_Document.sqlite
> _________.../Unsaved_Document 2.sqlite
> original: ../Unsaved_Document 2.sqlite
>
> saving auto elsewhere   => a file was autosaved
> file:____nil 
> store:.../Unsaved_Document.sqlite
> ______.../Unsaved_Document.sqlite
> orginal:./Unsaved_Document.sqlite.
> 
>....

So during autosave I should save my persistent store or, I guess, migrate it to a new location. If appkit wants me to migrate the store to new location (because a file was duplicated for example), then I would expect absoluteOriginalContentsURL to point to the original data and absoluteURL to the new location.

However both absoluteOriginalContentsURL and absoluteURL are always the same. Even worse, my persistent store points to the same file (on disk) for both documents. So if I do nothing, one document is going to overwrite the data of the other document.

But from within this function I have no idea whether to copy my store to the absoluteURL (data is copied, persistent store is unchanged) or to replace my store (current store is removed from the persistent store coordinator, new store is added).

To clarify: If I do nothing, both documents use to the same file and one document is using the wrong file. The duplicate document has the wrong information/store. If I migrate, then the original document has the wrong information or persistent store.

user965972
  • 2,489
  • 2
  • 23
  • 39
  • Why do you override `writeToURL`? – Willeke Mar 04 '16 at 21:49
  • Because NSPersistentDocument is in serious need of an overhaul? In my case I want to use a NSManagedObjectContext with private queue that talks to the persistent store and at least one NSManagedObjectContext for the user interface, one for background operations and as many context's more as needed. I don't see how that is possible without overwriting writeToURL. – user965972 Mar 04 '16 at 22:20
  • Override `managedObjectContext`? "If you want to customize the creation of the persistence stack, reimplement this property in your custom subclass and use your implementation to create the appropriate objects." – Willeke Mar 05 '16 at 11:13
  • Override managedObjectContext? The documentation explicitly states that you should not override managedObjectContext. Core data creates and deletes managedObjectContext's internally as it sees fit and that it will not rely on any properties of a custom NSManagedObjectContext. Furthermore, a custom core data stack does not require subclassing NSManagedObject. It requires setting the parent managed object context and specifying the concurrency type (main or private). – user965972 Mar 05 '16 at 12:35
  • Override the `managedObjectContext` property of `NSPersistentDocument`. – Willeke Mar 06 '16 at 13:47

0 Answers0