我怎样才能得到一个可写的path在iPhone上?

我发布这个问题,因为我有一个完整的答案写出来的另一个职位,当我发现它不适用于原来的,但我认为太浪费了太多有用。 因此,我也把这个社区维基做成了一个社区维基,以便其他人可以提出问题和答案。 如果你觉得这个答案有用,请把这个问题提出来 – 作为一个社区维基,我不应该得到这个投票的积分,但是它会帮助别人find它

我怎样才能得到一个文件写入允许在iPhone上的path? 你可以(误导性地)在模拟器上的任意位置写下任何东西,但在iPhone上只允许写入特定的位置。

有三种可写path可供考虑 – 第一种是文档,您可以在其中存储要保留的内容,并通过iTunes(3.2)提供给用户:

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *documentsDirectory = [paths objectAtIndex:0]; 

其次,与Documents目录非常相似,还有Library文件夹,您可以在其中存储configuration文件和可写入的数据库,但是您不希望用户能够通过iTunes进行混淆:

 NSArray *paths = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES); NSString *libraryDirectory = [paths objectAtIndex:0]; 

请注意,即使用户无法使用3.2以前的设备(iPad)在iTunes中查看文件,NSLibraryDirectory常量在iPhoneOS 2.0之后仍然可用,因此可用于定位3.0的构build(如果您还在做甚至更早那)。 此外,除非您将应用程序标记为允许用户修改文档,否则用户将无法看到任何内容,所以如果您今天正在使用文档,只要在更新用于支持用户文档的位置时更改位置即可。

最后有一个caching目录,在那里你可以把你不在乎的图像长期存在或不存在(手机可能在某个时候删除它们):

 NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES); NSString *cachePath = [paths objectAtIndex:0]; BOOL isDir = NO; NSError *error; if (! [[NSFileManager defaultManager] fileExistsAtPath:cachePath isDirectory:&isDir] && isDir == NO) { [[NSFileManager defaultManager] createDirectoryAtPath:cachePath withIntermediateDirectories:NO attributes:nil error:&error]; } 

请注意,你必须在那里创buildCaches目录,所以在写时你必须检查和创build每一个! 有种痛苦,但事实就是这样。

然后当你有一个可写的path时,你只需要在它上面附加一个文件名就可以了:

 NSString *filePath = [documentsDirectory stringByAppendingPathComponent:@"SomeDirectory/SomeFile.txt"]; 

要么

 NSString *filePath = [cachePath stringByAppendingPathComponent:@"SomeTmpFile.png"]; 

使用该path进行阅读或写作。

请注意,您可以在这些可写path中的任一个中创build子目录,上面的示例string中的一个正在使用(假设已经创build了一个)。

如果您正尝试将图像写入照片库,则不能使用文件系统调用来执行此操作,而必须在内存中使用UIImage,并使用由UIKit定义的UIImageWriteToSavedPhotosAlbum()函数调用。 您无法控制目标格式或压缩级别,也无法以此方式附加任何EXIF。

感谢上面的肯德尔和戴夫,我认为这个修正案很有用。 当使用一次性的debugging代码时,我使用了Mike Ash的NSBlog中的 这个技巧来消除临时variablesisDir&error,最大限度地减less了行数并使得冗长度几乎可以忍受:

 NSFileHandle *dumpFileHandle = nil; #ifdef DEBUG NSString *cachePath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) objectAtIndex:0]; if (![[NSFileManager defaultManager] fileExistsAtPath:cachePath isDirectory:&(BOOL){0}]) [[NSFileManager defaultManager] createDirectoryAtPath:cachePath withIntermediateDirectories:YES attributes:nil error:&(NSError*){nil}]; NSString *dumpPath = [cachePath stringByAppendingPathComponent:@"dump.txt"]; [[NSFileManager defaultManager] createFileAtPath:dumpPath contents:nil attributes:nil]; [(dumpFileHandle = [NSFileHandle fileHandleForWritingAtPath:dumpPath]) truncateFileAtOffset:0]; #endif if (dumpFileHandle) [dumpFileHandle writeData:blah];