写在前面:
以前对于iOS沙盒的理解还等留在Sdwebimage这个第三方的库上,就是项目中的一些缓存图片啊什么的放到Caches目录下进行缓存,避免了重复去下载。清除项目的缓存啊什么的我一般也只去操作这个文件夹,最近是因为要做一个离线地图包的下载,才发现了其中的问题~~
一、什么是沙盒机制
处于安全考虑,iOS系统的沙盒机制规定每个应用都只能访问当前沙盒目录下面的文件(也有例外,比如在用户授权情况下访问通讯录,相册等),这个规则展示了iOS系统的封闭性。
二、沙盒机制的结构
每个应用程序目录下有三个文件(Documents、Library、temp)以及一个.app的包,NSString *path = NSHomeDirectory();可以得到这个目录。
1.Documents目录:最常用的目录,iTunes同步该应用时会同步此文件夹中的内容,适合存储重要数据。
2.Library目录:包含两个子目录(Preferences、Caches)。
Preferences路径:包含程序的偏好设置文件,iTunes同步该应用时会同步此文件夹中的内容,通常保存应用的设置信息,我们常用的NSUserDefaults储存的数据就在这个路径下。
Caches路径:iTunes不会同步此文件夹,适合存储体积大,不需要备份的非重要数据。Sdwebimage缓存下来的图片文件就在这个文件下。
3.tmp目录:iTunes不会同步此文件夹,这个目录用于存放临时文件。tmp目录不是你程序退出的时候就清空,是在你内存不足的情况系统会给你清空。尽管iCloud不会备份这些文件,但在应用使用完这些数据之后要注意随时删除,避免占用用户设备的空间。
三、获取路径
//获取Documents目录路径
NSString*docDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES)firstObject];
//获取Library的目录路径
NSString*libDir = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory,NSUserDomainMask, YES)lastObject];
//获取Caches目录路径
NSString*cachesDir = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory,NSUserDomainMask, YES)firstObject];
//获取tmp目录路径
NSString*tmpDir =NSTemporaryDirectory();
写到这里大家可以发现,一般的缓存,数据多而且不是重要的文件我们缓存到Caches路径完全可以够用了。但是我的需求是下载一个比较重要的文件包,是绝对不会短期更新也不能被清理掉的,比如说那些音乐应用。可惜的是通过我的了解Caches路径下的东西系统也会清理。那么我的解决方案是什么呢?
解决:
所以,为了保险起见,最靠谱的还是放在/Documents中。我们在上面提到过了Documents目录是会被iCloud备份的,这也就会引起App需要备份的体积变大了,这也是苹果不允许的,甚至会被拒绝上架。那要怎么解决呢?所以我们既要把缓存的内容放入Dcouments中,又不能让iCloud备份。Apple已经提供了相应的函数,如下(iOS 5.1及以后的版本):
-(BOOL)addSkipBackupAttributeToItemAtURL:(NSURL*)URL{
assert([[NSFileManagerdefaultManager]fileExistsAtPath:[URL path]]);
NSError*error=nil;
BOOL success=[URL setResourceValue:[NSNumbernumberWithBool:YES]
forKey:NSURLIsExcludedFromBackupKeyerror:&error];
if(!success){
NSLog(@"Error excluding %@ from backup %@",[URL lastPathComponent],error);
}
return success;
}
参考文章: 一次审核被拒的经历-关于iCloud到底应该备份什么数据