How can I save an image to my app's tmp dir?
Asked Answered
M

4

22

Why is that if I use NSTemporaryDirectory to save my image, the image is saved into

/var/folders/oG/oGrLHcAUEQubd3CBTs-1zU+++TI/-Tmp-/

and not into

/Users/MyMac/Library/Application Support/iPhone Simulator/4.3.2/Applications/A685734E-36E9-45DD-BBE7-0A46F8F91DAF/tmp

Here is my code:

-(NSString *)tempPath
{
    return NSTemporaryDirectory();
}

-(void) saveMyFoto
{
    NSString *urlNahledu = [NSString stringWithFormat:@"%@%@%@",@"http://www.czechmat.cz", urlFotky,@"_100x100.jpg"];
    NSLog(@"%@", urlNahledu);


    UIImage *image = [[UIImage alloc] initWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:urlNahledu]]];

    NSData *data = [NSData dataWithData:UIImageJPEGRepresentation(image, 0.8f)];

    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);

    NSLog(@"%@    %@", paths, [self tempPath]);

    NSString *documentsDirectory = [paths objectAtIndex:0];
    NSString *localFilePath = [documentsDirectory stringByAppendingPathComponent:@"pkm.jpg"];

    [data writeToFile:localFilePath atomically:YES];
}
Motherinlaw answered 16/9, 2011 at 12:55 Comment(2)
This post explain all directories of iOS application, save, delete kmithi.blogspot.in/2012/08/…Mesopause
UIImageJPEGRepresentation() already returns NSData * - why did you pass it to dataWithData: before using it? I'm wondering if you know something that I don't...Frangipane
T
56

This is the preferred method which uses URL's to get a link directly to the tmp directory and then returns a file URL (pkm.jpg) for that directory:

Swift 5+

let url = URL(fileURLWithPath: NSTemporaryDirectory(), isDirectory: true)
    .appendingPathComponent("pkm", isDirectory: false)
    .appendingPathExtension("jpg")

// Then write to disk, here 0.8 is chosen for the compression quality
if let data = image.jpegData(compressionQuality: 0.8) {
    do {
        try data.write(to: url)
    } catch {
        print("Handle the error, i.e. disk can be full")
    }
}

Swift 4.1

let url = URL(fileURLWithPath: NSTemporaryDirectory(), isDirectory: true)
    .appendingPathComponent("pkm", isDirectory: false)
    .appendingPathExtension("jpg")

// Then write to disk, here 0.8 is chosen for the quality
if let data = UIImageJPEGRepresentation(image, 0.8) {
    do {
        try data.write(to: url)
    } catch {
        print("Handle the error, i.e. disk can be full")
    }
}

Swift 3.1

let tmpURL = try! URL(fileURLWithPath: NSTemporaryDirectory(), isDirectory: true)
                    .appendingPathComponent("pkm")
                    .appendingPathExtension("jpg")
print("Filepath: \(tmpURL)")

Note that a possible error is not handled!

Swift 2.0

let tmpDirURL = NSURL.fileURLWithPath(NSTemporaryDirectory(), isDirectory: true)
let fileURL = tmpDirURL.URLByAppendingPathComponent("pkm").URLByAppendingPathExtension("jpg")
print("FilePath: \(fileURL.path)")

Objective-C

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

Note that some methods still request a path as string, then use the [fileURL path] to return the path as string (as shown above in the NSLog). When upgrading a current App all files in the folders:

<Application_Home>/Documents/
<Application_Home>/Library/

are guaranteed to be preserved from the old version (excluding the <Application_Home>/Library/Caches subdirectory). Use the Documents folder for files you may want the user to have access to and the Library folder for files that the App uses and the User should not see.


Another longer way might be to get an url to the tmp directory, by first getting the Document directory and stripping the last path component and then adding the tmp folder:

NSURL *documentDir = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] firstObject];
NSURL *tmpDir = [[documentDir URLByDeletingLastPathComponent] URLByAppendingPathComponent:@"tmp" isDirectory:YES];
NSLog(@"tmpDir: %@", [tmpDir path]);

Then we can address a file there, i.e. pkm.jpg as shown here:

NSString *fileName = @"pkm";
NSURL *fileURL = [tmpDir URLByAppendingPathComponent:fileName isDirectory:NO];
fileURL = [fileURL URLByAppendingPathExtension:@"jpg"];

The same may be accomplished with strings, which was used by the way on older iOS systems, but the first URL method above is the recommended one now (unless you are writing to older systems: iPhone OS 2 or 3):

NSString *tmpDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
tmpDir = [[tmpDir stringByDeletingLastPathComponent] stringByAppendingPathComponent:@"tmp"];
NSString *filePath = [[tmpDir stringByAppendingPathComponent:@"pkm"] stringByAppendingPathExtension:@"jpg"];
Teen answered 18/8, 2012 at 23:37 Comment(3)
I cant get files from NSTemporaryDirectory () when is a video file .mp4. Works perfect for audio and image. HelpNinefold
@Ninefold I don't really understand your problem, but it may have to do with whether the file is supported by iOS.Teen
isDirectory is importantWain
D
3

Because apps running in the simulator are not really sandboxed like in iOS devices. On the simulator a temporary directory from Mac OS is returned in NSTemporaryDirectory() - on an iOS device the temporary directory is really within the sandbox. That difference shouldn't concern you as an app developer.

Dryden answered 16/9, 2011 at 13:17 Comment(0)
R
1

Swift 5 version of Sverrisson 's answer.

    let url = URL(fileURLWithPath: NSTemporaryDirectory(), isDirectory: true)
        .appendingPathComponent("pkm", isDirectory: false)
        .appendingPathExtension("jpg")
    
    // Then write to disk
    if let data = image.jpegData(compressionQuality: 0.8) {
        do {
            try data.write(to: url)
        } catch {
            print("Handle the error, i.e. disk can be full")
        }
    }
Rathenau answered 19/2, 2021 at 7:28 Comment(0)
B
-2

If you want to store your images in /Users/MyMac/Library/Application Support/iPhone Simulator/4.3.2/Applications/A685734E-36E9-45DD-BBE7-0A46F8F91DAF/tmp

then use nshomedirectory() which give you location upto /Users/MyMac/Library/Application Support/iPhone Simulator/4.3.2/Applications/A685734E-36E9-45DD-BBE7-0A46F8F91DAF then you just put /tmp and store your images.

        NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, 
                                                     NSUserDomainMask, YES); 
NSString* docDir = [paths objectAtIndex:0];
NSString* file = [docDir stringByAppendingString:@"/tmp"];
Bighead answered 16/9, 2011 at 13:33 Comment(1)
This does not work and the text talks of NSHomeDirectory() and the code uses NSDocumentDirectory thus, the /tmp directory will be part of Documents directory which is wrong.Teen

© 2022 - 2024 — McMap. All rights reserved.