I'm using NSFileWrapper
for my package document. Sometimes, when I request the data of a file inside the package I get nil
.
This is how I query the data of a file inside the package:
- (NSData*) dataOfFile(NSString*)filename {
NSFileWrapper *fileWrapper = [self.documentFileWrapper.fileWrappers objectForKey:filename];
return fileWrapper.regularFileContents; // This returns nil sometimes. Why?
}
This method eventually starts returning nil for some files (not all). Sadly, I haven't managed to reproduce the problem consistently.
In case it helps, this is how I open the package:
- (BOOL) readFromFileWrapper:(NSFileWrapper *)fileWrapper ofType:(NSString *)typeName error:(NSError *__autoreleasing *)outError {
self.documentFileWrapper = fileWrapper;
return YES;
}
This is how I update the data of a file inside the package:
- (void) updateFile:(NSString*)filename withData:(NSData*)data {
SBFileWrapper *fileWrapper = [self.documentFileWrapper.fileWrappers objectForKey:filename];
if (fileWrapper) {
[self.documentFileWrapper removeFileWrapper:fileWrapper];
}
NSFileWrapper *fileWrapper = [[SBFileWrapper alloc] initRegularFileWithContents:data ];
fileWrapper.preferredFilename = filename;
[self.documentFileWrapper addFileWrapper:fileWrapper];
}
This is how I save the package:
- (NSFileWrapper*) fileWrapperOfType:(NSString *)typeName error:(NSError *__autoreleasing *)outError {
return self.documentFileWrapper;
}
Why can this be happening? Is there a way to prevent it?
The documentation of regularFileContents
appears to talk about this problem:
This method may return nil if the user modifies the file after you call readFromURL:options:error: or initWithURL:options:error: but before NSFileWrapper has read the contents of the file. Use the NSFileWrapperReadingImmediate reading option to reduce the likelihood of that problem.
But I don't understand what has to be changed in the code above to prevent this situation.
Failed Experiments
I tried saving the document if regularFileContents
return nil but it still returns nil afterwards. Like this:
- (NSData*) dataOfFile(NSString*)filename {
NSFileWrapper *fileWrapper = [self.documentFileWrapper.fileWrappers objectForKey:filename];
NSData *data = fileWrapper.regularFileContents;
if (!data) {
[self saveDocument:nil];
fileWrapper = [self.documentFileWrapper.fileWrappers objectForKey:filename];
data = fileWrapper.regularFileContents;
}
return data;
}