94

Let's say I have a folder in my "Resources" folder of my iPhone application called "Documents".

Is there a way that I can get an array or some type of list of all the files included in that folder at run time?

So, in code, it would look like:

NSMutableArray *myFiles = [...get a list of files in Resources/Documents...];

Is this possible?

CodeGuy
  • 28,427
  • 76
  • 200
  • 317

7 Answers7

140

You can get the path to the Resources directory like this,

NSString * resourcePath = [[NSBundle mainBundle] resourcePath];

Then append the Documents to the path,

NSString * documentsPath = [resourcePath stringByAppendingPathComponent:@"Documents"];

Then you can use any of the directory listing APIs of NSFileManager.

NSError * error;
NSArray * directoryContents = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:documentsPath error:&error];

Note : When adding source folder into the bundle make sure you select "Create folder references for any added folders option when copying"

Lithu T.V
  • 19,955
  • 12
  • 56
  • 101
Deepak Danduprolu
  • 44,595
  • 12
  • 101
  • 105
37

Swift

Updated for Swift 3

let docsPath = Bundle.main.resourcePath! + "/Resources"
let fileManager = FileManager.default

do {
    let docsArray = try fileManager.contentsOfDirectory(atPath: docsPath)
} catch {
    print(error)
}

Further reading:

Community
  • 1
  • 1
Suragch
  • 484,302
  • 314
  • 1,365
  • 1,393
  • 4
    Error Domain=NSCocoaErrorDomain Code=260 "The folder “Resources” doesn’t exist." UserInfo={NSFilePath=/var/containers/Bundle/Application/A367E139-1845-4FD6-9D7F-FCC7A64F0408/Robomed.app/Resources, NSUserStringVariant=( Folder ), NSUnderlyingError=0x1c4450140 {Error Domain=NSPOSIXErrorDomain Code=2 "No such file or directory"}} – Argus Oct 31 '18 at 13:03
  • I just removed + "/Resources" and got something. I'm not sure what to do with the values in the array I got back. – MarkAurelius Jan 13 '21 at 10:40
  • Dear readers, I'm not currently updating my iOS answers. It appears this is one of them that could use some updating, though. If you solve the problems written in the comments above, feel free to edit my answer and correct it. – Suragch Jan 14 '21 at 00:39
18

You can try this code also:

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSError * error;
NSArray * directoryContents =  [[NSFileManager defaultManager]
                      contentsOfDirectoryAtPath:documentsDirectory error:&error];

NSLog(@"directoryContents ====== %@",directoryContents);
neowinston
  • 7,584
  • 10
  • 52
  • 83
  • you're allocating an array in directoryContents that is immediately overwritten by an array returns by contentsOfDir... – Joris Weimar Feb 18 '14 at 00:30
  • What I meant to show was just an array that would hold the contents of the directory. The array is there just for example's sake. I've edited it slightly. – neowinston Feb 18 '14 at 15:19
18

Swift version:

    if let files = try? FileManager.default.contentsOfDirectory(atPath: Bundle.main.bundlePath ){
        for file in files {
            print(file)
        }
    }
johndpope
  • 5,035
  • 2
  • 41
  • 43
Matt Frear
  • 52,283
  • 12
  • 78
  • 86
8

Listing All Files In A Directory

     NSFileManager *fileManager = [NSFileManager defaultManager];
     NSURL *bundleURL = [[NSBundle mainBundle] bundleURL];
     NSArray *contents = [fileManager contentsOfDirectoryAtURL:bundleURL
                           includingPropertiesForKeys:@[]
                                              options:NSDirectoryEnumerationSkipsHiddenFiles
                                                error:nil];

     NSPredicate *predicate = [NSPredicate predicateWithFormat:@"pathExtension ENDSWITH '.png'"];
     for (NSString *path in [contents filteredArrayUsingPredicate:predicate]) {
        // Enumerate each .png file in directory
     }

Recursively Enumerating Files In A Directory

      NSFileManager *fileManager = [NSFileManager defaultManager];
      NSURL *bundleURL = [[NSBundle mainBundle] bundleURL];
      NSDirectoryEnumerator *enumerator = [fileManager enumeratorAtURL:bundleURL
                                   includingPropertiesForKeys:@[NSURLNameKey, NSURLIsDirectoryKey]
                                                     options:NSDirectoryEnumerationSkipsHiddenFiles
                                                errorHandler:^BOOL(NSURL *url, NSError *error)
      {
         NSLog(@"[Error] %@ (%@)", error, url);
      }];

      NSMutableArray *mutableFileURLs = [NSMutableArray array];
      for (NSURL *fileURL in enumerator) {
      NSString *filename;
      [fileURL getResourceValue:&filename forKey:NSURLNameKey error:nil];

      NSNumber *isDirectory;
      [fileURL getResourceValue:&isDirectory forKey:NSURLIsDirectoryKey error:nil];

       // Skip directories with '_' prefix, for example
      if ([filename hasPrefix:@"_"] && [isDirectory boolValue]) {
         [enumerator skipDescendants];
         continue;
       }

      if (![isDirectory boolValue]) {
          [mutableFileURLs addObject:fileURL];
       }
     }

For more about NSFileManager its here

Govind
  • 2,337
  • 33
  • 43
  • 3
    It will not work if the extenison has the '.'. In other word, this will work: [NSPredicate predicateWithFormat:@"pathExtension ENDSWITH 'png'"]; – Liangjun Jul 08 '14 at 16:14
6

Swift 4:

If you have to do with subdirs "Relative to project" (blue folders) you could write:

func getAllPListFrom(_ subdir:String)->[URL]? {
    guard let fURL = Bundle.main.urls(forResourcesWithExtension: "plist", subdirectory: subdir) else { return nil }
    return fURL
}

Usage:

if let myURLs = getAllPListFrom("myPrivateFolder/Lists") {
   // your code..
}
Alessandro Ornano
  • 34,887
  • 11
  • 106
  • 133
5

Swift 3 (and returning URLs)

let url = Bundle.main.resourceURL!
    do {
        let urls = try FileManager.default.contentsOfDirectory(at: url, includingPropertiesForKeys:[], options: FileManager.DirectoryEnumerationOptions.skipsHiddenFiles)
    } catch {
        print(error)
    }
narco
  • 830
  • 8
  • 21