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]

Reply via email to