pixelbitlabs
pixelbitlabs

Reputation: 1934

List saved files in iOS documents directory in a UITableView?

I have set up the following code to save a file to the documents directory:

NSLog(@"Saving File...");

NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.reddexuk.com/logo.png"]];
AFHTTPRequestOperation *operation = [[[AFHTTPRequestOperation alloc] initWithRequest:request] autorelease];

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *path = [[paths objectAtIndex:0] stringByAppendingPathComponent:@"logo.png"];
operation.outputStream = [NSOutputStream outputStreamToFileAtPath:path append:NO];

[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
    NSLog(@"Successfully downloaded file to %@", path);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
    NSLog(@"Error: %@", error);
}];

[operation start];

However, I wish to add each file to a UITableView when it is successfully saved. When the file in the UITableView is tapped, I'd like a UIWebView to navigate to that file (all offline).

Also - how can I just get the filename and ending such as "logo.png" instead of http://www.reddexuk.com/logo.png?

How can I do this?

Upvotes: 58

Views: 72150

Answers (9)

Marián Černý
Marián Černý

Reputation: 15738

Swift 5

Function that returns array of URLs of all files in Documents directory that are MP4/M4V videos. If you want all files, just remove the filter.

It checks only files in the top directory. If you want to list also files in the subdirectories, remove the .skipsSubdirectoryDescendants option.

func listVideos() -> [URL] {
    let fileManager = FileManager.default
    let documentDirectory = fileManager.urls(for: .documentDirectory, in: .userDomainMask)[0]

    let files = try? fileManager.contentsOfDirectory(
        at: documentDirectory,
        includingPropertiesForKeys: nil,
        options: [.skipsSubdirectoryDescendants, .skipsHiddenFiles]
    ).filter {
        ["mp4", "m4v"].contains($0.pathExtension.lowercased())
    }

    return files ?? []
}

Upvotes: 3

Alex Zavatone
Alex Zavatone

Reputation: 4323

I know this is an old question, but it's a good one and things have changed in iOS post Sandboxing.

The path to all the readable/writeable folders within the app will now have a hash in it and Apple reserves the right to change that path at any time. It will change on every app launch for sure.

You'll need to get the path to the folder you want and you can't hardcode it like we used to be able to do in the past.

You ask for the documents directory and in the return array, it's at position 0. Then from there, you use that value to supply to the NSFileManager to get the directory contents.

The code below works under iOS 7 and 8 to return an array of the contents within the documents directory. You may want to sort it according to your own preferences.

+ (NSArray *)dumpDocumentsDirectoryContents {

    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsPath = [paths objectAtIndex:0];

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

    NSLog(@"%@", directoryContents);
    return directoryContents;
}

Upvotes: 6

DogCoffee
DogCoffee

Reputation: 19946

Thanks Alex,

Here is Swift version

let paths = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)
let documentDirectory = paths[0]
if let allItems = try? FileManager.default.contentsOfDirectory(atPath: documentDirectory) {
    print(allItems)
}

Upvotes: 8

footyapps27
footyapps27

Reputation: 4042

Swift 3.x

let documentDirectory = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]
if let allItems = try? FileManager.default.contentsOfDirectory(atPath: documentDirectory) {
  print(allItems)
}

Upvotes: 1

FertoVordalastr
FertoVordalastr

Reputation: 71

NSDirectoryEnumerator *dirEnum = [[NSFileManager defaultManager] enumeratorAtPath:dir_path];

NSString *filename;

while ((filename = [dirEnum nextObject]))
{
    // Do something amazing
}

for enumerating through ALL files in directory

Upvotes: 2

mattt
mattt

Reputation: 19544

For a more reasonable filename:

NSString *filename = [[url lastPathComponent] stringByAppendingPathExtension:[url pathExtension]];

Upvotes: 4

Mike Martin
Mike Martin

Reputation: 376

-(NSArray *)findFiles:(NSString *)extension{

NSMutableArray *matches = [[NSMutableArray alloc]init];
NSFileManager *fManager = [NSFileManager defaultManager];
NSString *item;
NSArray *contents = [fManager contentsOfDirectoryAtPath:[NSHomeDirectory() stringByAppendingPathComponent:@"Documents"] error:nil];

// >>> this section here adds all files with the chosen extension to an array
for (item in contents){
    if ([[item pathExtension] isEqualToString:extension]) {
        [matches addObject:item];
    }
}
return matches; }

The example above is pretty self-explanatory. I hope it answers you second question.

Upvotes: 21

coneybeare
coneybeare

Reputation: 33101

To get the contents of a directory

- (NSArray *)ls {
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    NSArray *directoryContent = [[NSFileManager defaultManager] directoryContentsAtPath: documentsDirectory];

    NSLog(@"%@", documentsDirectory);
    return directoryContent;
}

To get the last path component,

[[path pathComponents] lastObject]

Upvotes: 11

syclonefx
syclonefx

Reputation: 2990

Here is the method I use to get the content of a directory.

-(NSArray *)listFileAtPath:(NSString *)path
{
    //-----> LIST ALL FILES <-----//
    NSLog(@"LISTING ALL FILES FOUND");

    int count;

    NSArray *directoryContent = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:path error:NULL];
    for (count = 0; count < (int)[directoryContent count]; count++)
    {
        NSLog(@"File %d: %@", (count + 1), [directoryContent objectAtIndex:count]);
    }
    return directoryContent;
}

Upvotes: 145

Related Questions