问题
想通过文件管理器读取某个沙盒文件
解决方案
方案1
事先用户通过Document保存文件,通过保存bookmarkData来实现再次读取,类似方式也可以通过缓存在本地实现
// 创建一个UIDocumentPickerViewController实例
UIDocumentPickerViewController *documentPicker = [[UIDocumentPickerViewController alloc] initWithDocumentTypes:@[(NSString *)kUTTypeData] inMode:UIDocumentPickerModeOpen];
// 设置代理
documentPicker.delegate = self;
// 呈现选择器
[self presentViewController:documentPicker animated:YES completion:nil];
用户选择文件后,保存bookmarkData用于下次读取【也可以作为缓存保存在本地】
#pragma mark - UIDocumentPickerDelegate
- (void)documentPicker:(UIDocumentPickerViewController *)controller didPickDocumentAtURL:(NSURL *)fileURL {
// 检查是否是文件URL
if (fileURL.isFileURL) {
// 获取文件的本地路径
NSString *filePath = fileURL.path;
NSLog(@"filePath:%@",filePath);
// 请求访问安全受限的资源
if ([fileURL startAccessingSecurityScopedResource]) {
NSError *error;
NSData *bookmarkData = [fileURL bookmarkDataWithOptions:NSURLBookmarkCreationMinimalBookmark
includingResourceValuesForKeys:nil
relativeToURL:nil
error:&error];
NSString * bookmarkDataString = [bookmarkData base64EncodedStringWithOptions:0];
[kUserDefaults setObject:bookmarkDataString forKey:@"bookmarkData"];
if (!bookmarkData) {
// 处理无法获取书签数据的情况
NSLog(@"Failed to get bookmark data: %@", error);
}
NSError *error1;
BOOL isStale = false;
NSURL *directoryURL = [NSURL URLByResolvingBookmarkData:bookmarkData
options:NSURLBookmarkResolutionWithoutUI
relativeToURL:nil
bookmarkDataIsStale:&isStale
error:&error1];
if (!directoryURL) {
// 处理解析出的 URL 为空的情况
NSLog(@"Failed to resolve bookmark data: %@", error);
return;
}
[fileURL stopAccessingSecurityScopedResource];
} else {
// 无法获取访问权限
NSLog(@"无法开始访问安全受限的资源");
}
}
}
读取文件手段
NSError *error1;
BOOL isStale = false;
NSString * bookmarkDataString = [kUserDefaults objectForKey:@"bookmarkData"];
NSData *bookmarkData = [[NSData alloc] initWithBase64EncodedString:bookmarkDataString options:0];
NSURL *fileURL = [NSURL URLByResolvingBookmarkData:bookmarkData
options:NSURLBookmarkResolutionWithoutUI
relativeToURL:nil
bookmarkDataIsStale:&isStale
error:&error1];
// 请求访问安全受限的资源
if ([fileURL startAccessingSecurityScopedResource]) {
// 访问权限已获取,可以安全地读取文件数据
NSError *error = nil;
NSData *fileData = [NSData dataWithContentsOfURL:fileURL options:NSDataReadingMappedIfSafe error:&error];
if (fileData) {
// 成功读取文件数据
NSLog(@"文件数据大小: %lu bytes", (unsigned long)fileData.length);
// 在这里处理你的NSData对象
} else {
// 读取文件时发生错误
NSLog(@"读取文件错误: %@", error.localizedDescription);
}
// 完成文件操作后,停止访问安全受限的资源
[fileURL stopAccessingSecurityScopedResource];
} else {
// 无法获取访问权限
NSLog(@"无法开始访问安全受限的资源");
}
方案2
单纯只是打开文件,让用户自己选择处理方式
// 文件路径
NSString *filePath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject] stringByAppendingPathComponent:@"文件.txt"];
// 检查文件是否存在
if ([[NSFileManager defaultManager] fileExistsAtPath:filePath]) {
NSURL *fileURL = [NSURL fileURLWithPath:filePath];
UIDocumentInteractionController *documentInteractionController = [UIDocumentInteractionController interactionControllerWithURL:fileURL];
documentInteractionController.delegate = self;
// 弹出文件操作菜单
[documentInteractionController presentOpenInMenuFromRect:CGRectZero inView:self.view animated:YES];
} else {
NSLog(@"File does not exist at path: %@", filePath);
}
方案3
单纯打开文件管理器并跳转到指定文件那里
// 文件路径
NSString *filePath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject] stringByAppendingPathComponent:@"文件.txt"];
NSURL *fileURL = [NSURL fileURLWithPath:filePath];
if (fileURL) {
NSURLComponents *components = [NSURLComponents componentsWithURL:fileURL resolvingAgainstBaseURL:YES];
components.scheme = @"shareddocuments";
NSURL *sharedFileURL = [components URL];
if (sharedFileURL) {
[[UIApplication sharedApplication] openURL:sharedFileURL options:@{} completionHandler:nil];
}
}