Contrary to the accepted answer, the difference is not only availability. The FileManager API actually accesses the file pointed to by the URL on the disk to see if it is a directory, whereas hasDirectoryPath does not; it only checks whether the URL's path has a slash (/) at the end of it, which indicates that the path points to a directory. You can verify this by making an app and running it in the File Activity instrument; with FileManager you will see an lstat64 on the directory, whereas with hasDirectoryPath you will not.
This has a few effects:
hasDirectoryPath will obviously perform much faster, since it does not access the disk.
However, hasDirectoryPath may give incorrect results if the URL's path is incorrect regarding the presence of the trailing slash. For example:
URL(string: "file:///usr/bin")!.hasDirectoryPath // evaluates to false
URL(string: "file:///usr/bin/")!.hasDirectoryPath // evaluates to true
Finally, hasDirectoryPath can work on a non-file: URL, such as an http: URL, whereas FileManager obviously cannot.
With all that said, when you need to check via the file system, it is better to use the URL-based mechanism for this rather than path-based ones in FileManager:
let isDir = (try? self.resourceValues(forKeys: [.isDirectoryKey]))?.isDirectory ?? false