前段时间,客户提出了一个需求,希望可以像微信一个从云盘中选择文件发送。
还好苹果提供了 UIDocumentPickerViewController
这个控制器,可以让我们很方便的达成这个目的。
添加对 iCloud 的支持
首先要打开 Target
-> Capabilities
-> iCloud
,选择 iCloud Documents
。
然后我们到 Apple Developer
中创建一个 iCloud Containers
。ID 按照 Xcode 提示命名就好。
分析 UIDocumentPickerViewController
创建一个 UIDocumentPickerViewController
- (instancetype)initWithDocumentTypes:(NSArray <NSString *>*)allowedUTIs inMode:(UIDocumentPickerMode)mode NS_DESIGNATED_INITIALIZER;
第一个参数指定了允许显示的类型标识符集合。 参考: System-Declared Uniform Type Identifiers
要想显示所有文件则直接指定 @[@"public.item"]
第二个参数 mode
有四种,但是 UIDocumentPickerViewController
只支持UIDocumentPickerModeImport
和 UIDocumentPickerModeOpen
。
实现代理方法 - (void)documentPicker:(UIDocumentPickerViewController *)controller didPickDocumentAtURL:(NSURL *)url
处理外部文件。
对于处理外部文档是有一些限制的:
- 对于要处理的
URL
,要使用startAccessingSecurityScopedResource
和stopAccessingSecurityScopedResource
方法使其进入 安全范围 操作。 - 使用 NSFileCoordinator 读写外部文档。
- 使用 NSFilePresenter 显示外部文档内容。
简单实现
从iCloud Drive 选择文件保存到本地
- (void)showFileFromICouldDrive {
UIDocumentPickerViewController *picker = [[UIDocumentPickerViewController alloc] initWithDocumentTypes:@[@"public.item"] inMode:UIDocumentPickerModeImport];
picker.delegate = self;
picker.modalPresentationStyle = UIModalPresentationFormSheet;
[self presentViewController:picker animated:YES completion:^{
}];
}
- (void)documentPicker:(UIDocumentPickerViewController *)controller didPickDocumentAtURL:(NSURL *)url
{
[url startAccessingSecurityScopedResource];
NSFileCoordinator *coordinator = [[NSFileCoordinator alloc] init];
__block NSError *error;
[coordinator coordinateReadingItemAtURL:url options:NSFileCoordinatorReadingResolvesSymbolicLink error:&error byAccessor:^(NSURL * _Nonnull newURL) {
NSLog(@"newURL %@, error :%@", newURL, error);
NSError *ferror;
[[NSFileManager defaultManager] copyItemAtURL:newURL toURL:[NSURL fileURLWithPath:filePath] error:&ferror];
if (ferror) {
NSLog(@"copy iCloud file error : %@", ferror);
}
}];
[url stopAccessingSecurityScopedResource];
}