Reputation: 17866
I’m working on an NSDocument-based application whose document type is a package bundle that contains a bunch of files. I’m saving it thus:
- (NSFileWrapper *)fileWrapperOfType:(NSString *)typeName error:(NSError **)outError
{
if (!self.documentFileWrapper) {
NSFileWrapper *documentFileWrapper = [[NSFileWrapper alloc] initDirectoryWithFileWrappers:nil];
[self setDocumentFileWrapper:documentFileWrapper];
}
NSFileWrapper *defaultWrapper = [self.documentFileWrapper.fileWrappers objectForKey:@"default"];
if (!defaultWrapper) {
defaultWrapper = [[NSFileWrapper alloc] initDirectoryWithFileWrappers:nil];
[defaultWrapper setPreferredFilename:@"someFile.ext"];
[self.documentFileWrapper addFileWrapper:defaultWrapper];
}
[defaultWrapper addRegularFileWithContents: ... some computed content for the file ... preferredFilename:@"someFile.ext"];
return self.documentFileWrapper;
}
In other words, into the bundle, create a folder “default”, and save “someFile.ext” into it with some contents.
Now, the problem. When I go look at what’s actually saved on disk, I see this:
Every time I save the file, the NSDocument wrapper seems to create some versioned copy of the resource. I don’t want the versioned clones, I only want the vanilla file with the latest content.
Where do the versioned resources come from? What’s going on here? Is there a doc I should read?
Upvotes: 1
Views: 505
Reputation: 215
You could implement -writeSafely… so that it calls straight through to -writeToURL:… Implement -writeToURL:… so that it calls -fileWrapperOfType:… and then writes that out to the URL atomically
i.e. you'd be taking over responsibility for atomic saves by making NSFileWrapper do it. That way the wrapper should neatly track where the files really end up.
Upvotes: 1
Reputation: 4462
Ok, I think I figured it out. As it turns out, it wasn't actually a versioning issue. It appears that you were simply adding a new file each time. First, a few notes.
Now, your actual problem: according to this documentation, addRegularFileWithContents
creates a new file with your preferred filename, unless the directory (defaultWrapper
) already contains a file with that name (basically). If there already is, it creates a new file with a prefix. addRegularFileWithContents
returns an identifying string referring to the NSFileWrapper created (I think it's the filename).
So, what's happening is that each time you go to save the file, it sees that there's already a file of that name, and creates a new prefixed one. One way to solve this is to keep the NSString returned by addRegularFileWithContents
, then when you go to save you check the defaultWrapper
and remove the NSFileWrapper associated with the stored NSString, if there is one, and then add the file like normal. I've modified your code as follows:
@interface TestDocument () // Relevant part of my test class. Note `wrapperFileName`.
@property (nonatomic, strong) NSFileWrapper *documentFileWrapper;
@property (nonatomic, strong) NSString *wrapperFileName;
@end
- (NSFileWrapper *)fileWrapperOfType:(NSString *)typeName error:(NSError **)outError
{
if (!self.documentFileWrapper) {
NSFileWrapper *documentFileWrapper = [[NSFileWrapper alloc] initDirectoryWithFileWrappers:nil];
[self setDocumentFileWrapper:documentFileWrapper];
}
NSFileWrapper *defaultWrapper = [self.documentFileWrapper.fileWrappers objectForKey:@"default"];
if (!defaultWrapper) {
defaultWrapper = [[NSFileWrapper alloc] initDirectoryWithFileWrappers:nil];
[defaultWrapper setPreferredFilename:@"default"];
[self.documentFileWrapper addFileWrapper:defaultWrapper];
} else if (self.wrapperFileName) {
[defaultWrapper removeFileWrapper:[[defaultWrapper fileWrappers] objectForKey:self.wrapperFileName]];
}
self.wrapperFileName = [defaultWrapper addRegularFileWithContents:[@"blah blah" dataUsingEncoding:NSUTF8StringEncoding] preferredFilename:@"someFile.txt"];
return self.documentFileWrapper;
}
defaultWrapper
's preferred filename to be "default", as I suspect you intended.if
block that removes the previously saved file, if one existed.After these changes, the program demonstrated what I think is the behavior you expect: one directory containing one file, even after saving multiple times. Note that this was true even when preservesVersions
returned YES
. I'm not sure where it stores its versions, but I didn't see them.
Upvotes: 2