官方文档解析
官方文档:https://developer.apple.com/documentation/uikit/uidocumentpickerviewcontroller?language=objc
UIDocumentPickerViewController有四种模式:
- Import an external document:用户选择一个外部文档,文档选择器拷贝该文档到应用沙盒,不会修改源文档。
- Export a local document:文档选择器拷贝文档到一个外部路径,不会修改源文档。
- Open an external document:打开一个外部文档,用户可以修改该文档。
- Move a local document:拷贝文档到外部路径,同时可以修改该拷贝。
操作外部文件注意事项
- open与move操作会提供外部文件的
security-scoped
URL 。调用startAccessingSecurityScopedResource
开始访问,访问完成调用stopAccessingSecurityScopedResource
。 - 使用
NSFileCoordinator
来操作外部文件 - 使用
NSFilePresenter
来展示外部文件内容 - 不要存储
security-scoped
URL
调用Demo
展示文件选择
- (void)presentDocumentPicker {
NSArray *types = @[]; // 可以选择的文件类型
UIDocumentPickerViewController *documentPicker = [[UIDocumentPickerViewController alloc] initWithDocumentTypes:types inMode:UIDocumentPickerModeOpen];
documentPicker.delegate = self;
documentPicker.modalPresentationStyle = UIModalPresentationFullScreen;
[self presentViewController:documentPicker animated:YES completion:nil];
}
用户选择文件回调
- (void)documentPicker:(UIDocumentPickerViewController *)controller didPickDocumentAtURL:(NSURL *)url {
BOOL canAccessingResource = [url startAccessingSecurityScopedResource];
if(canAccessingResource) {
NSFileCoordinator *fileCoordinator = [[NSFileCoordinator alloc] init];
NSError *error;
[fileCoordinator coordinateReadingItemAtURL:url options:0 error:&error byAccessor:^(NSURL *newURL) {
NSData *fileData = [NSData dataWithContentsOfURL:newURL];
NSArray *arr = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentPath = [arr lastObject];
NSString *desFileName = [documentPath stringByAppendingPathComponent:@"myFile"];
[fileData writeToFile:desFileName atomically:YES];
[self dismissViewControllerAnimated:YES completion:NULL];
}];
if (error) {
// error handing
}
} else {
// startAccessingSecurityScopedResource fail
}
[url stopAccessingSecurityScopedResource];
}
文件类型定义
initWithDocumentTypes:inMode:
中,types需要传入一个uniform type identifiers (UTIs)数组。关于UTIs的官方文档,常见列表