tarabyte
tarabyte

Reputation: 19192

How to copy NSData contents to temporary file?

I'm downloading what can be a large file from an S3 bucket and want to save it between view controllers to be consumed a short time later. I like the tmp directory because of less limitations on file size and there also does not seem to be a reason for me to save this in the Documents directory.

I can construct a path to tmp with:

        NSURL *tmpDirURL = [NSURL fileURLWithPath:NSTemporaryDirectory() isDirectory:YES];
        NSURL *fileURL = [[tmpDirURL URLByAppendingPathComponent:@"image"] URLByAppendingPathExtension:@"png"];
        NSLog(@"fileURL: %@", [fileURL path]);

but am unsure how to write/overwrite the downloaded NSData * to that path.

I basically just want to what I can more clearly express with the command line:

wget https://example.com/image.png
cp image.png /tmp/

Looks like the class reference may expose a method to do just this:

https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSData_Class/

EDIT

My solution that works. Ended up being that I needed to use writeToURL. Inspiration taken from here: http://nshipster.com/nstemporarydirectory/ https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSURL_Class/#//apple_ref/occ/clm/NSURL/fileURLWithPath:isDirectory:

    #define S3_LATEST_IMAGE_FILEPATH   @"test-image.png"

    // Write the downloaded result to the filesystem
    NSError *error;
    NSString *fileName = [NSString stringWithFormat:@"%@_%@", [[NSProcessInfo processInfo] globallyUniqueString], S3_LATEST_IMAGE_FILEPATH];
    NSURL *directoryURL = [NSURL fileURLWithPath:[NSTemporaryDirectory() stringByAppendingPathComponent:[[NSProcessInfo processInfo] globallyUniqueString]] isDirectory:YES];
    [[NSFileManager defaultManager] createDirectoryAtURL:directoryURL withIntermediateDirectories:YES attributes:nil error:&error];
    if (error) {
      NSLog(@"Error1: %@", error);
      return;
    }
    NSURL *fileURL = [directoryURL URLByAppendingPathComponent:fileName];

    NSString *path = fileURL.absoluteString;
    NSLog(@"fileURL.absoluteString: %@", path);
    [data writeToURL:fileURL options:NSDataWritingAtomic error:&error];
    if (error) {
      NSLog(@"Error: %@", error);
    }

Upvotes: 2

Views: 3359

Answers (1)

ipraba
ipraba

Reputation: 16553

You can directly write the NSData into the path by

NSURL *tmpDirURL = [NSURL fileURLWithPath:NSTemporaryDirectory() isDirectory:YES];
NSURL *fileURL = [[tmpDirURL URLByAppendingPathComponent:@"newest-fw"] URLByAppendingPathExtension:@"zip"];
NSString *path= fileURL.absoluteString;
//data would be the NSData that you get from the S3 bucket
NSError *error;
[[NSFileManager defaultManager] createDirectoryAtURL: fileURL withIntermediateDirectories:NO attributes:nil error:&error];
[data writeToFile:path options:NSDataWritingAtomic error:&error];

NSData's writeToFile method will automatically overwrite the file if it is previously present.

Upvotes: 5

Related Questions