Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
322 views
in Technique[技术] by (71.8m points)

iphone - is saving in NSDocumentDirectory okay?

My app is using the NSDocumentDirectory to save images in it, I just wanna ask if its the safe way to save images(100 maximum). I have read several thread & questions with answers about it, though I dont know which to follow.Some say that its okay to save there. Some say I shouldnt use NSDocumentDirectory for saving, because it will be back-up by the iCloud. So where can I save it that when the user exit the app then run the app again, then images should still be there?. I dont know much about the tmp directory or cache directory. But if its either one of the 2 that I should use, How can I use them in my code here:

                NSArray *paths = NSSearchPathForDirectoriesInDomains( NSDocumentDirectory,    NSUserDomainMask ,YES );
                NSString *documentsDir = [paths objectAtIndex:0];
                NSString *savedImagePath = [documentsDir stringByAppendingPathComponent:[NSString stringWithFormat:@"Images%d.png", i]];
                ALAssetRepresentation *rep = [[info objectAtIndex: i] defaultRepresentation];
                UIImage *image = [UIImage imageWithCGImage:[rep fullResolutionImage]];
                //----resize the images
                image = [self imageByScalingAndCroppingForSize:image toSize:CGSizeMake(256,256*image.size.height/image.size.width)];

                NSData *imageData = UIImagePNGRepresentation(image);
                [imageData writeToFile:savedImagePath atomically:YES];

Thank you so much for the help.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

The tmp and cache directories are periodically cleaned up by iOS. If the images are for general use, use the camera roll as the other two answers suggest. However if these images are intended just for the scope of your app, you can still safely store them in the Documents directory, you just have to include an "exclude from iCloud backup" function call to each file after saving, in order to prevent Apple rejecting your app for using too much iCloud space. Of course there's a trade-off, disabling this means the user will lose their photos anyway should they delete the app or get another device(etc), but this caveat is preferable to not getting the App on the store at all.

To disable iCloud backup on a file, there's two methods for iOS versions > 5.0:

UPDATE! MERGED BOTH METHODS INTO A SINGLE FUNCTION THAT AUTOMATICALLY HANDLES iOS VERSION:

#include <sys/xattr.h> // Needed import for setting file attributes

+(BOOL)addSkipBackupAttributeToItemAtURL:(NSURL *)fileURL {

    // First ensure the file actually exists
    if (![[NSFileManager defaultManager] fileExistsAtPath:[fileURL path]]) {
        NSLog(@"File %@ doesn't exist!",[fileURL path]);
        return NO;
    }

    // Determine the iOS version to choose correct skipBackup method
    NSString *currSysVer = [[UIDevice currentDevice] systemVersion];

    if ([currSysVer isEqualToString:@"5.0.1"]) {
        const char* filePath = [[fileURL path] fileSystemRepresentation];
        const char* attrName = "com.apple.MobileBackup";
        u_int8_t attrValue = 1;
        int result = setxattr(filePath, attrName, &attrValue, sizeof(attrValue), 0, 0);
        NSLog(@"Excluded '%@' from backup",fileURL);
        return result == 0;
    }
    else if (&NSURLIsExcludedFromBackupKey) {
        NSError *error = nil;
        BOOL result = [fileURL setResourceValue:[NSNumber numberWithBool:YES] forKey:NSURLIsExcludedFromBackupKey error:&error];
        if (result == NO) {
            NSLog(@"Error excluding '%@' from backup. Error: %@",fileURL, error);
            return NO;
        }
        else { // Succeeded
            NSLog(@"Excluded '%@' from backup",fileURL);
            return YES;
        }
    } else {
        // iOS version is below 5.0, no need to do anything
        return YES;
    }
}

If your app must support 5.0, then unfortunately your only option is to save those photos in the Caches directory, which means they won't be backed up (this not causing an App Store rejection for that reason), but whenever the storage watchdog decides it's time to clean the Caches folder, you'll lose those photos. Not an ideal implementation at all, but such is the nature of the beast in 5.0, where Apple added in Backup exclusion as an afterthought.

EDIT: Forgot to answer the 'how to save to the tmp/cache directory' part of the question. If you do decide to go down that path:

  • Saving to tmp:

    NSString *tempDir = NSTemporaryDirectory();
    NSString *savedImagePath = [tempDir stringByAppendingPathComponent:[NSString stringWithFormat:@"Images%d.png", i]];
    

(note that this won't appear to have any effect in the simulator, but it works as expected on device)

  • Saving to Cache:

    NSString *cacheDir = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory,NSUserDomainMask,YES)lastObject];
    NSString *savedImagePath = [cacheDir stringByAppendingPathComponent:[NSString stringWithFormat:@"Images%d.png", i]];
    

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...