每个iOS程序都有一个独立的文件系统(存储空间),而且只能在对应的文件系统中进行操作,此区域被称为沙盒。应用必须待在自己的沙盒里,其他应用不能访问该沙盒。所有的非代码文件都要保存在此,例如属性文件plist、文本文件、图像、图标、媒体资源等。如下图:
沙盒中相关路径
AppName.app
应用程序的程序包目录,包含应用程序的本身。由于应用程序必须经过签名,所以不能在运行时对这个目录中的内容进行修改,否则会导致应用程序无法启动。
Documents/
保存应用程序的重要数据文件和用户数据文件等。用户数据基本上都放在这个位置(例如从网上下载的图片或音乐文件),该文件夹在应用程序更新时会自动备份,在连接iTunes时也可以自动同步备份其中的数据。
Library
:这个目录下有两个子目录,可创建子文件夹。可以用来放置您希望被备份但不希望被用户看到的数据。该路径下的文件夹,除Caches以外,都会被iTunes备份.
Library/Caches
: 保存应用程序使用时产生的支持文件和缓存文件(保存应用程序再次启动过程中需要的信息),还有日志文件最好也放在这个目录。iTunes 同步时不会备份该目录并且可能被其他工具清理掉其中的数据。Library/Preferences
: 保存应用程序的偏好设置文件。NSUserDefaults
类创建的数据和plist
文件都放在这里。会被iTunes备份。
tmp/
: 保存应用运行时所需要的临时数据。不会被iTunes备份。iPhone重启时,会被清空。
因为每个app下的沙盒路径都是封闭的,其他应用访问不到,也就导致了文件不能共享。只能自己在代码中维护本app内的文件。这给用户带来很多的不便。因此,苹果除了一个系统的“文件”的app,用来管理app内的文件。但是系统的“文件”这个app不是可以管理全部的app下的文件,他只能管理对“文件”这个app开放权限的APP。
在你的 App 内的文件可以出现在 Files 里面之前,你必须保证你的 App 是支持 Files 中打开并且可以分享的。这需要你在你的 App 内的 Info.plist 中添加两个键值对,第一个是 UIFileSharingEnabled,这个可以使 iTunes 分享你文件夹内的内容;第二个是 LSSupportsOpeningDocumentsInPlace ,它保证了你文件夹内本地文件的获取权限,你需要将这两个键值对的值设置为 YES ,如下:
Application supports iTunes file sharing | YES |
Supports opening documents in place | YES |
接着,再运行程序,打开系统中“文件”的app,就可以获取就可以在 Files 里面 我的 iPhone 中看到以你项目名为文件夹名的文件夹(如果你在 Files 中看不到 我的 iPhone这一项,你只需要在照片中选中一张照片共享到 Files 里面,就可以看到这一项了)。
在 Files 里面的文件夹,会将沙盒内 Documents 文件夹内的所有文件都显示出来,因此对一些私密的文件来说是不安全的,那么应该如何避免呢?
这个取决于它的重要性,如果它不是那么重要的,我们可以将它们存放在 cachesDirectory 或者是 temporaryDirectory 文件夹下面;如果它是重要的文件,大多数情况下,我们是需要将它们备份在 iCloud 上的,这样的文件我们建议将它存放在 applicationSupportDirectory 目录下。
一般我们用icould来实现文件的共享,但是icould的存储空间只有5G,远远不够。但是“文件”的app可以获取到对“Files”开放权限的app的文件,那么我们可以通过 "UIDocumentPickerViewController"这个控制器来打开“文件”app的文件。使用步骤:
(1)集成2个代理:
(2)在需要的控制器中,打开“UIDocumentPickerViewController”;
//打开文件管理的控制
- (void)presentDocumentCloud {
NSArray *documentTypes = @[@"public.text",
@"public.content",
@"public.source-code",
@"public.image",
@"public.audiovisual-content",
@"com.adobe.pdf",
@"com.apple.keynote.key",
@"com.microsoft.word.doc",
@"com.microsoft.excel.xls",
@"com.microsoft.powerpoint.ppt"];
UIDocumentPickerViewController *documentPickerViewController = [[UIDocumentPickerViewController alloc] initWithDocumentTypes:documentTypes inMode:UIDocumentPickerModeImport];
documentPickerViewController.delegate = self;
[self presentViewController:documentPickerViewController animated:YES completion:nil];
}
(3)实现代理:
#pragma mark - UIDocumentPickerDelegate
- (void)documentPicker:(UIDocumentPickerViewController *)controller didPickDocumentAtURL:(NSURL *)url {
NSArray *array = [[url absoluteString] componentsSeparatedByString:@"/"];
NSString *fileName = [array lastObject];
fileName = [fileName stringByRemovingPercentEncoding];
NSLog(@"--->>>>%@",fileName);
//在此已获取到文件,可对文件进行需求上的操作
// if ([self iCloudEnable]) {
if (![NSData dataWithContentsOfURL:url]) {
[QMUITips showWithText:@"只能选择本文件夹下的文件"];
return;
}
// }
}
- (BOOL)iCloudEnable {
NSFileManager *manager = [NSFileManager defaultManager];
NSURL *url = [manager URLForUbiquityContainerIdentifier:nil];
if (url != nil) {
return YES;
}
NSLog(@"iCloud 不可用");
UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@"icloud" message:@"iCloud 不可用, 不能选择文件上传" delegate:nil cancelButtonTitle:@"取消" otherButtonTitles:@"确定", nil];
[alert show];
return NO;
}
其中需要注意的是,第二步中,documentController的Mode有4种类型:
目前,我只能用前两种,前两种是读取和查看;后两种,猜测是把本地文件放到“文件”下的路径,也就是微信中,“存储到"文件"”的类似操作,但是因为我在项目中,没有配置icloud的证书,所以不能用后两种。
待研究,估计是把documentController的Mode改成ExportToService上。但是需要配置icould,配置icoould的教程如下链接:
https://www.jianshu.com/p/50348b35c986
配置iCloud,首先你就先要有一个真实的苹果开发者账号,没错,就是一年688的那个。开通了之后,在Xcode中新建一个项目。然后在 TARGETS
-> Capabilities
-> iCloud
中打开开关就可以了。
就像这样,是不是很简单啊。
诶,可是好像有什么地方不对,有些地方爆红了。
这是因为我们还没有给这个App ID 注册,所以接下来我们去苹果的 开发者官网 添加一个App ID,在添加的时候勾选 iCloud
服务就可以啦。
什么?你说你已经创建过App ID了???没关系,在管理App ID这边选择 Edit
,然后在勾选iCloud
也是一样的。
这时候回到Xcode中在看一下,应该就已经没有爆红了吧。
什么???还有爆红??? 那你重启一下XCode试试吧。再不行,你重启一下电脑试试好了
所以,不要再说,只能维护本app的文件了,苹果已经对外开放这个文件管理这个功能了!!!!
参考文档:
https://www.jianshu.com/p/50348b35c986
https://www.jianshu.com/p/61b4e26ab413