iOS App 的 Documents 目錄下有一個子資料夾(如 POIs),裡面存放大量圖片。需要一次性讀取該資料夾下所有圖片的檔案名稱,存入 NSArray 供後續業務使用(如列表顯示、批量上傳等)。
FileManager.default 提供了 contentsOfDirectory(atPath:) 方法,可直接返回指定路徑下所有檔案/資料夾的名稱陣列([String]),這是最高效的單次讀取方式。
let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
let poisFolderURL = documentsURL.appendingPathComponent("POIs")
do {
let fileNames = try FileManager.default.contentsOfDirectory(atPath: poisFolderURL.path)
// fileNames 為 [String],包含所有檔案/資料夾名稱
print("讀取到 \(fileNames.count) 個項目:\(fileNames)")
// 後續可篩選副檔名、排序等
} catch {
print("讀取失敗:\(error.localizedDescription)")
}
let imageExtensions = ["jpg", "jpeg", "png", "gif", "heic", "webp"]
let imageNames = fileNames.filter { name in
let ext = (name as NSString).pathExtension.lowercased()
return imageExtensions.contains(ext)
}
let imageURLs = imageNames.map { poisFolderURL.appendingPathComponent($0) }
// 或一次性獲取 URL 陣列(含屬性)
let imageURLs = try FileManager.default.contentsOfDirectory(
at: poisFolderURL,
includingPropertiesForKeys: [.contentModificationDateKey, .fileSizeKey],
options: [.skipsHiddenFiles]
).filter { imageExtensions.contains($0.pathExtension.lowercased()) }
若資料夾檔案極多(數千以上),建議放在背景隊列執行:
DispatchQueue.global(qos: .userInitiated).async {
do {
let urls = try FileManager.default.contentsOfDirectory(
at: poisFolderURL,
includingPropertiesForKeys: nil,
options: .skipsHiddenFiles
)
let imageURLs = urls.filter { ["jpg","png","heic"].contains($0.pathExtension.lowercased()) }
DispatchQueue.main.async {
self.updateUI(with: imageURLs)
}
} catch {
DispatchQueue.main.async { self.showError(error) }
}
}
contentsOfDirectory 會拋出錯誤,先用 fileExists(atPath:) 判斷或用 try? 忽略。.DS_Store 等隱藏檔,加 .skipsHiddenFiles 選項自動跳過。.lowercased()。NSFileManager *fm = [NSFileManager defaultManager];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsPath = paths[0];
NSString *poisPath = [documentsPath stringByAppendingPathComponent:@"POIs"];
NSError *error = nil;
NSArray *fileNames = [fm contentsOfDirectoryAtPath:poisPath error:&error];
if (error) {
NSLog(@"Error: %@", error.localizedDescription);
} else {
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"pathExtension IN %@", @[@"jpg", @"png", @"jpeg"]];
NSArray *imageNames = [fileNames filteredArrayUsingPredicate:predicate];
NSLog(@"Images: %@", imageNames);
}
使用 FileManager.contentsOfDirectory(atPath:) 即可一行代碼完成「全選讀取檔名」的需求。配合副檔名過濾、非同步載入、URL 陣列轉換,即可構建健壯的圖片資源管理模組。Swift 版本語法更簡潔、類型安全,建議新專案優先採用。