0

In a function, I retrieve a list of directories. I would like to allow the function to accept a filter parameter to filter the retrieval before returning the directories.

This is my function:

public func getDocumentPaths(filter: ???? = nil) -> [String] {
    do {
        var directoryUrls = try NSFileManager.defaultManager().contentsOfDirectoryAtURL(...)

        // TODO: Filter the directory contents if applicable
        if filter != nil {
            directoryUrls = directoryUrls.filter(filter)
        }

        return directoryUrls.map { $0.absoluteString }
    } catch let error as NSError {
        return [String]()
    }
}

In the end, I'd like to call the function like this:

getDocumentPaths()
getDocumentPaths { $0.pathExtension == "mp3" }

What is the filter parameter type to allow this?

UPDATE: Based on @phimage's suggestion, I made the above function more Swift 2.0-like. Even more so, FileKit looks great!

public func getDocumentPaths() -> [String] {
    // Get the directory contents including folders
    guard let directoryUrls = try? NSFileManager.defaultManager().contentsOfDirectoryAtURL(NSURL(string:"")!, includingPropertiesForKeys: nil, options: []) else {
            // Failed so return empty list
            return [String]()
    }

    return directoryUrls.map { $0.path! }
}
Community
  • 1
  • 1
TruMan1
  • 27,054
  • 46
  • 150
  • 273
  • 1
    Note that (probably) `absoluteString` is *not* what you want to convert the urls to strings, use the `path` method instead. See http://stackoverflow.com/questions/34135305/nsfilemanager-defaultmanager-fileexistsatpath-returns-false-instead-of-true for a similar problem. – Martin R Jan 21 '16 at 20:04

1 Answers1

4

If you want to filter on NSURL

func getDocumentPaths(filter: ((NSURL) -> Bool)? = nil) -> [String] {
    do {
        var directoryUrls = try NSFileManager.defaultManager().contentsOfDirectoryAtURL(NSURL(string:"")!, includingPropertiesForKeys: nil, options: [])   //contentsOfDirectoryAtURL(NSURL(string:"")!)

        // Filter the directory contents if applicable
        if let f = filter {
            directoryUrls = directoryUrls.filter(f)
        }

        return directoryUrls.map { $0.path }
    } catch {
        return [String]()
    }
}

If you want to filter on absolute string

func getDocumentPaths(filter: ((String) -> Bool)? = nil) -> [String] {
    do {
        var directoryUrls = try NSFileManager.defaultManager().contentsOfDirectoryAtURL...


        var directoryStrings = directoryUrls.map { $0.path }
        // Filter the directory contents if applicable
        if let f = filter {
            directoryStrings = directoryStrings.filter(f)
        }

        return directoryStrings
    } catch {
        return [String]()
    }
}

ps: log or rethrow the exception

ps2: you can use library like FileKit to manage files easily, there is find method

phimage
  • 274
  • 1
  • 6