Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UIDocument, NSFileWrapper and Images

I have an UIDocument which I'd like to be comprised of (1) a txt file and (2) several jpg images. I put the txt and all the jpgs into a NSFileWrapper.

When I load the UIDocument, I need the info in the txt file really quickly, so I load it first and ignore all the images until I actually need them.

While I know how to lazily load the images, I'm not sure how to "lazily" save the images (especially when using iCloud, I don't want files to be unnecessarily uploaded/download). Let's suppose I've loaded all the images and did not change them. Then I want to save the UIDocument, ignoring all the images (as they haven't changed) but want to save the text as it did change.

How would I achieve this? Is it even possible? Or is it automatically done? Or should I rather not put the images in my UIDocument and let each image be handled by a different UIDocument? It's all a bit confusing to me, I'm afraid.

Here's my code so far which will save all the images and text (no matter whether they were changed or not):


UIDocument

-(id)contentsForType:(NSString *)typeName error:(NSError *__autoreleasing *)outError {

        NSMutableDictionary *wrappers = [NSMutableDictionary dictionary];
// the following puts a wrapper into a dictionary of wrappers:
        [self encodeObject:self.text toWrappers:wrappers toFileName:@"text.data"];
        [self encodeObject:self.photos toWrappers:wrappers toFileName:@"photos.data"];
        NSFileWrapper *fileWrapper = [[NSFileWrapper alloc] initDirectoryWithFileWrappers:wrappers];

        return fileWrapper;

    }

When I want to save the UIDocument:

[self.doc saveToURL:self.doc.fileURL forSaveOperation:UIDocumentSaveForOverwriting completionHandler:^(BOOL success) {
    [self.doc closeWithCompletionHandler:^(BOOL success) {}];
}];
like image 591
n.evermind Avatar asked Jun 11 '12 16:06

n.evermind


1 Answers

You should keep a reference to your NSFileWrapper in your UIDocument instance. This way, only the changed contents will be rewritten and not the whole wrapper.

So, keep a reference when you load a file (or create a new one for new documents) :

- (BOOL)loadFromContents:(id)contents ofType:(NSString *)typeName error:(NSError **)outError {
    // save wrapper:
    self.fileWrapper = (NSFileWrapper*)contents;

now you only have to update the wrapper if your file actually changed:

- (id)contentsForType:(NSString *)typeName error:(NSError **)outError {
    NSFileWrapper *subwrapper = [self.fileWrapper.wrappers objectForKey:@"subwrapper"];
    if(self.somethingChanged) {
        [self.fileWrapper.wrappers removeFileWrapper:subwrapper];
        subwrapper = [[NSFileWrapper alloc] initRegularFileWithContents:…

I know the code is very brief, but I hope that helps to point you in the right direction.

like image 86
auco Avatar answered Nov 19 '22 23:11

auco