保存在NSDocumentDirectory好吗?

我的应用程序正在使用NSDocumentDirectory保存图像,我只想问是否安全的方式来保存图像(最大100)。 我已经阅读了几个线程和问题的答案,虽然我不知道要跟随。有人说,它可以保存在那里。 有人说我不应该使用NSDocumentDirectory进行保存,因为它将由iCloud备份。 那么我在哪里可以保存,当用户退出应用程序,然后再次运行应用程序,那么图像应该仍然在那里? 我不太了解tmp目录或cache目录。 但是,如果它是我应该使用的2中的任何一个,我怎样才能在我的代码中使用它们:

  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]; 

十分感谢你的帮助。

tmpcache目录由iOS定期清理。 如果图像是一般用途,请使用相机胶卷作为另外两个答案build议。 但是,如果这些图像只是为了您的应用程序的范围,您仍然可以安全地将它们存储在Documents目录中,您只需在保存后为每个文件包含一个“从iCloud备份中排除”function调用,以防止Apple拒绝使用太多iCloud空间的应用程序。 当然,这是一个折衷,禁用这意味着用户将删除应用程序或获得另一个设备(等等)无论如何都将失去他们的照片,但是这个警告是不要在商店得到应用程序。

要禁用文件上的iCloud备份,iOS版本> 5.0有两种方法:

UPDATE! 将两种方法合并成一个自动处理iOS版本的单一function:

 #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; } } 

如果您的应用程序必须支持5.0,那么不幸的是,您唯一的select是将这些照片保存在Caches目录中,这意味着它们将不会被备份(这不会导致App Store因为这个原因而被拒绝),但是只要存储监督机构是时候清理caching文件夹,你会失去这些照片。 根本不是一个理想的实现,但是在5.0版本中,这是野兽的本质,苹果在备份排除中join了这个事实。

编辑:忘了回答“如何保存到tmp / cache目录”部分的问题。 如果你决定走这条路:

  • 保存到tmp

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

(注意,这在模拟器中似乎没有任何作用,但它在设备上按预期工作)

  • 保存到Cache

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

如果您希望用户能够使用其他应用程序中的图像或查看他们的照片,请使用Mike Dbuild议的相册。 如果文件是本地生成的,仅用于您的应用程序,那么您应该使用文档目录。 您可以使用info.plist选项“应用程序支持iTunes文件共享”将文档目录暴露给iTunes,这将允许用户通过iTunes添加或删除文件,但这些文件不会暴露给其他应用程序

您正在保存缩放的图像,以便它们只对您的游戏有用。 他们不会很大,不会占用太多的空间。 您可以将它们保存在应用程序的库目录中,并避免整个iCloud的事情,因为它听起来不像是有任何理由来备份它们。 此外,保存库避免了用户删除它们的可能性,如果由于其他原因打开了iTunes共享。

更新:保存到应用程序库目录的代码

 - (void)saveSequences:(NSMutableDictionary*)sequences { NSArray *path = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES); NSString *libDirectory = [path objectAtIndex:0]; NSString *settingsPath = [libDirectory stringByAppendingPathComponent:@"userSequences.plist"]; NSLog(@"settingsPath %@", settingsPath); [sequences writeToFile:settingsPath atomically:YES]; } 

//下面的代码获取到“文档”文件夹中指定目录的path – 如果它不存在,创build它。 调整它以使用库path,如果你决定去那条路线。

 - (NSString *)getDirectoryBySequenceName:(NSString *)sequenceName { NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString * documentDirectory = [paths objectAtIndex:0]; NSString * sequenceDirectory = [documentDirectory stringByAppendingPathComponent:sequenceName]; NSError *error; BOOL success = [[NSFileManager defaultManager] createDirectoryAtPath:sequenceDirectory withIntermediateDirectories:YES attributes:nil error:&error]; if (!success) { NSLog(@"Error creating data path: %@", [error localizedDescription]); } return sequenceDirectory; } 

根据你的应用程序的目的,你可以将它保存到照片应用程序( UIImageWriteToSavedPhotosAlbum(image, self, nil, nil)我认为, 苹果的参考 )。 保存在这里,或在文档目录(或任何子文件夹),将允许用户备份这些图像到iCloud或iTunes,如果用户也select和/或如果他们已经build立了iCloud。

由于您声明图像需要在启动之间保持不变,当应用程序从内存中删除时,temp或cache目录可能会被清空(O / S决定)。

更多关于iOS文件系统 。