Thanks for your insights.
how long is the deepest file path?
Not long. In the video they showed how the removed directory is only 2 levels deep and every filename is 10-20 characters long.
Are you able to remove the sub-directory they added?
Like I mentioned, with FileManager.removeItem(atPath:) I wasn't able to, but with my custom function below that recursively removes files before the containing folder and I sent to them in a test app today, it worked (and no error alerts were shown).
(Note: before macOS 10.15, the code will leave empty sub-directories and try to remove the top-level directory at the end.)
func removeFileRecursively(atPath path: String) -> Bool {
if case let url = URL(fileURLWithPath: path, isDirectory: false), (try? url.resourceValues(forKeys: [.isDirectoryKey]).isDirectory) == true {
var options: FileManager.DirectoryEnumerationOptions = []
if #available(macOS 10.15, *) {
options.insert(.includesDirectoriesPostOrder)
}
guard let enumerator = FileManager.default.enumerator(at: url, includingPropertiesForKeys: [.isDirectoryKey, .isUserImmutableKey], options: options, errorHandler: { url, error in
NSAlert(error: error).runModal()
return true
}) else {
return false
}
while let url = enumerator.nextObject() as? URL {
let isDirectory = (try? url.resourceValues(forKeys: [.isDirectoryKey]).isDirectory) == true
let shouldRemove = if #available(macOS 10.15, *) {
!isDirectory || enumerator.isEnumeratingDirectoryPostOrder
} else {
!isDirectory
}
if shouldRemove {
do {
if try url.resourceValues(forKeys: [.isUserImmutableKey]).isUserImmutable == true {
try (url as NSURL).setResourceValues([.isUserImmutableKey: false])
}
if #available(macOS 10.15, *) {
let result = if isDirectory {
rmdir(url.path)
} else {
unlink(url.path)
}
if result < 0 {
throw NSError(domain: NSPOSIXErrorDomain, code: Int(errno))
}
} else {
try FileManager.default.removeItem(at: url)
}
} catch {
NSAlert(error: error).runModal()
return false
}
}
}
}
do {
try FileManager.default.removeItem(atPath: path)
} catch {
NSAlert(error: error).runModal()
return false
}
return true
}