Cocoa中使用contentsOfDirectoryAtPath获取文件夹内容遇nil问题求助
解决NSFileManager获取文件夹内容返回nil的问题
老兄,你现在的问题核心是直接忽略了error参数,这就导致你根本不知道为什么在其他文件夹下会返回nil!先把错误信息抓出来,才能精准定位问题,然后我们一步步解决:
第一步:先获取错误信息,定位问题根源
不要把error设为nil,声明一个NSError指针传进去,当dirContents返回nil时,打印错误信息,就能知道是路径无效、权限不够还是其他问题:
NSError *error = nil; NSArray *dirContents = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:updated error:&error]; if (!dirContents) { NSLog(@"获取文件夹内容失败:%@", error.localizedDescription); return; }
常见的错误原因可能有这些:
updated路径根本不存在- 路径指向的是文件而不是文件夹
- 当前程序没有访问该文件夹的权限(比如macOS沙盒限制)
第二步:先验证路径的有效性
在获取内容前,先确认路径是存在的文件夹:
BOOL isDirectory = NO; BOOL exists = [[NSFileManager defaultManager] fileExistsAtPath:updated isDirectory:&isDirectory]; if (!exists) { NSLog(@"路径不存在:%@", updated); return; } if (!isDirectory) { NSLog(@"路径指向的不是文件夹:%@", updated); return; }
第三步:处理权限问题(重点!)
如果是用户手动选中的文件夹,在macOS沙盒环境下,你不能直接访问任意路径,必须通过NSOpenPanel让用户主动选择,然后保存安全范围书签,后续才能持续访问:
// 弹出选择文件夹面板 NSOpenPanel *openPanel = [NSOpenPanel openPanel]; openPanel.canChooseDirectories = YES; openPanel.canChooseFiles = NO; openPanel.allowsMultipleSelection = NO; if ([openPanel runModal] == NSModalResponseOK) { NSURL *selectedDirURL = openPanel.URL; // 保存安全范围书签,用于后续访问 NSData *bookmark = [selectedDirURL bookmarkDataWithOptions:NSURLBookmarkCreationWithSecurityScope includingResourceValuesForKeys:nil relativeToURL:nil error:&error]; if (bookmark) { // 把bookmark存在用户偏好设置里,下次启动可以复用 [[NSUserDefaults standardUserDefaults] setObject:bookmark forKey:@"SelectedDirBookmark"]; [[NSUserDefaults standardUserDefaults] synchronize]; // 开始访问文件夹 if ([selectedDirURL startAccessingSecurityScopedResource]) { // 这里获取文件夹内容 NSArray *dirContents = [[NSFileManager defaultManager] contentsOfDirectoryAtURL:selectedDirURL includingPropertiesForKeys:nil options:0 error:&error]; if (dirContents) { // 把内容添加到NSMenuItem子菜单的逻辑 for (NSURL *fileURL in dirContents) { NSMenuItem *item = [[NSMenuItem alloc] initWithTitle:[fileURL lastPathComponent] action:nil keyEquivalent:@""]; // 添加到子菜单 [yourSubMenu addItem:item]; } } // 结束访问 [selectedDirURL stopAccessingSecurityScopedResource]; } } }
这样处理后,不管用户选哪个文件夹,你都能合法访问它的内容啦!
内容的提问来源于stack exchange,提问作者Pankaj Mundra
相关产品推荐
相关产品推荐

