Autosave + non-file URL's == trouble
Autosave + non-file URL's == trouble
- Subject: Autosave + non-file URL's == trouble
- From: Charles Srstka <email@hidden>
- Date: Sun, 21 Jun 2015 15:02:01 -0500
Hi all,
I’ve got an app that can read files from normal file:/// <file:///> URLs, and also URLs with a custom scheme of my design. This all works pretty well as long as autosavesInPlace returns false. However, when I change autosavesInPlace to return true, suddenly I get this console warning on opening a document with my custom URL:
Failed to read draft status extended attribute for document at: /Foo. No such file or directory
What it’s apparently doing is to use the path portion of my non-file URL and interpret it as if it *were* a file URL, and then try to set an extended attribute on it. Obviously, we can’t have this. If the path component of the URL happened to coincide with a path to some actual file on the file system, we would mangle it, which is clearly unacceptable behavior.
One would think that setting the document’s ‘draft’ property to false would be sufficient to tell the system that this, in fact, isn’t a draft, but this has effect on this warning. A little digging through the assembly reveals the following:
- NSDocument’s initWithContentsOfURL:ofType:error: calls a private initializer, _initWithContentsOfURL:ofType:error:.
- _initWithContentsOfURL:ofType:error:, after it has called readFromURL:ofType:error:, checks the value of autosavesInPlace, and if it is true, calls a few different methods, one of which is called _readFileIsDraft. There are no branches that can avoid this method other than returning false on autosavesInPlace, returning true for isInViewingMode, or hitting an error condition.
- _readFileIsDraft does the following:
- asks for the NSDocument’s fileURL
- calls fileSystemRepresentation on the URL without checking if it is actually a file URL first
- goes to town doing stuff with the C path.
Okay, so we need to prevent this from happening, and since it’s baked right into initWithContentsOfURL:ofType:error:, it would seem that the only way to avoid this is to override that method myself, call the ordinary init method on super, and reimplement the rest of the method myself. But here’s where the catch comes in — this project is in Swift, which means initWithContentsOfURL:ofType:error: is marked as a convenience initializer, which means that it cannot be overridden even though the documentation says it’s perfectly fine and dandy to do so (rdar://21477980 <rdar://21477980>). NSDocument’s initWithContentsOfURL:ofType:error: method is called by NSDocumentController’s makeDocumentWithContentsOfURL:ofType:error:, so I could override that, but this is starting to get to be a lot of reimplementing methods without calling super, and it seems like there’s gotta be a better way.
How do you guys deal with non-file URLs and autosave?
Thanks,
Charles
_______________________________________________
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