Search code examples
swiftmacosapinsfilemanagerhidden-files

OS X API to enumerate a folder including AppleDouble files (beginning with a "._")?


The following 4 NSFileManager API fail to enumerate AppleDouble files beginning with a "._"

enumeratorAtPath, enumeratorAtURL, contentsOfDirectoryAtPath, contentsOfDirectoryAtURL

Which API should be used to get them enumerated without fail?


Solution

  • The below does the job, just in case someone needs it

    func contentsOfDirectoryUsingCAPI() -> [String]? {
        var contentsOfDirectory: [String]?
    
        if let folderPathCString = fileURL.path!.cStringUsingEncoding(NSUTF8StringEncoding) {
            // Open the directory
            let dir = opendir(folderPathCString)
    
            if dir != nil {
                contentsOfDirectory = []
    
                // Use readdir to get each element
                var entry = readdir(dir)
    
                while entry != nil {
                    let d_namlen = entry.memory.d_namlen
                    let d_name = entry.memory.d_name
    
                    // dirent.d_name is defined as a tuple with
                    // MAXNAMLEN elements.  We want to convert
                    // that to a null-terminated C string.                    
                    var nameBuf: [CChar] = Array()
                    let mirror = Mirror(reflecting: d_name)
    
                    for _ in 0..<d_namlen {
                        for child in mirror.children {
                            if let value = child.value as? CChar {
                                nameBuf.append(value)
                            }
                        }
                    }
    
                    // Null-terminate it and convert to a String
                    nameBuf.append(0)
                    if let name = String.fromCString(nameBuf) {
                        contentsOfDirectory?.append(name)
                    }
    
                    entry = readdir(dir)
                }
    
                closedir(dir)
            }
        }
    
        return contentsOfDirectory
    }