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 protected])
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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com
This email sent to [email protected]