I have been using Swift's [enumerator(at:includingPropertiesForKeys:options:)]
1 to find all files within a given base path and create arrays for different resource keys (file name, path, creation date, etc). This has worked well, but I noticed that the elements in the created arrays are not ordered by their creation date, which is what I need before I pass the elements of these arrays into a loop to upload each file in their date order.
I therefore need to somehow sort the elements of all resulting arrays by their creation date, a property that I am able to extract within its own array (using the .creationDateKey resource key). I therefore have two options (I think):
What's the best way to do this? I thought it would be straightforward, but have not found it so.
All advice graciously received. Thanks.
Here is my code:
// get URL(s) and other attributes of file(s) to be uploaded
let localFileManager = FileManager()
let resourceKeys = Set<URLResourceKey>([.nameKey, .pathKey, .creationDateKey, .isDirectoryKey])
let directoryEnumerator = localFileManager.enumerator(at: baseURL, includingPropertiesForKeys: Array(resourceKeys), options: .skipsHiddenFiles)!
var fileURLs: [URL] = []
var fileNames: [String] = []
var filePaths: [String] = []
var fileDates: [Date] = []
for case let fileURL as URL in directoryEnumerator {
guard let resourceValues = try? fileURL.resourceValues(forKeys: resourceKeys),
let isDirectory = resourceValues.isDirectory,
let name = resourceValues.name,
let path = resourceValues.path,
let date = resourceValues.creationDate,
else {
continue
}
if isDirectory {
if name == "_extras" { // use this to exclude a given directory
directoryEnumerator.skipDescendants()
}
} else {
// append elements in date order here?
fileURLs.append(fileURL) // full URLs of files
fileNames.append(name) // file names only
filePaths.append(path) // paths of file
fileDates.append(date) // date and time that file was created
// sort arrays by creation date here?
}
}
print(fileURLs)
print(fileNames)
print(filePaths)
print(fileDates)
You should not use multiple arrays for this but instead wrap your values in a custom struct
struct FileInfo {
let url: URL
let name: String
let path: String //this is not really needed, you can get it from the url
let date: Date
}
and have one array for this
var files: [FileInfo]()
and create your struct instance and append it
files.append(FileInfo(url: fileURL, name: name, path: path, date: date)
Sorting will now be trivial so after the for loop you do
files.sort(by: { $0.date < $1.date })
This sorts in ascending order, not sure which one you want.