Search code examples
swiftmacosnstableview

Get the Contents of multiple files in directory


I need to get the contents from multiple plist files and bring them into a single dictionary which is then displayed in a tableView

Using this code I can manually get each path and the contents of the file but I need to be able to do this for all plist files in the directory not just these predefined ones.

    func getFiles() {
    let documentDirectory = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] as String
    let path = documentDirectory.appending("/MainFolder/File1.plist")
    let path1 = documentDirectory.appending("/MainFolder/File2.plist")
    let path2 = documentDirectory.appending("/MainFolder/File3.plist")
    tableViewData = [NSDictionary(contentsOfFile: path) as! [String : String], NSDictionary(contentsOfFile: path1) as! [String : String], NSDictionary(contentsOfFile: path2) as! [String : String]]
    print(tableViewData)
}

I the display tableViewData in my tableView which gives me each files contents on its own row.

I am guessing I probably need an array of file urls filtered by .plist and then some way to get the contents of each file into a [String : String] dictionary.

I am new to swift, any help or a better way to do this would be great


Solution

  • First of all don't use outdated and objective-c-ish NSSearchPathForDirectoriesInDomains in Swift. Use the modernFileManager API.

    Second of all don't use objective-c-ish NSDictionary(contentsOf to read property list data. Use PropertyListSerialization.

    The function throws that means it hands over all possible errors to the caller. It filters the URLs in the directory by the plist extension and uses the map function to get the dictionary for each URL.

    func getFiles() throws {
        let documentDirectory = try FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false)
        let subFolderURL = documentDirectory.appendingPathComponent("MainFolder")
        let allFiles = try FileManager.default.contentsOfDirectory(at: subFolderURL, includingPropertiesForKeys: nil)
        let properListFiles = allFiles.filter{$0.pathExtension == "plist"}
        tableViewData = try properListFiles.compactMap { url -> [String:String]? in
            let data = try Data(contentsOf: url)
            return try PropertyListSerialization.propertyList(from: data, format: nil) as? [String:String]
        }
        print(tableViewData)
    }
    

    Be aware that in sandboxed apps the Documents folder is located in the application container.