Feb 21 2017
Source hidden to protect the guilty (who otherwise write very good code, but this jumped out)
let urls = FileManager.default.urls(for: .libraryDirectory, in: .userDomainMask)
print(urls[urls.count-1] as NSURL)
For the searchMask .libraryDirectory, this function always returns an array containing a single URL,[file:///Users/username/Library/]
so urls[urls.count-1] will give you urls, but it’s not clear from the code that this is what you’re doing.
You could, of course, use
let singleURL = try! FileManager.default.url(for: .libraryDirectory, in: .userDomainMask, appropriateFor: nil, create: false)
which is a more awkward to use (throwing) method, and ideally one would handle the error rather than assuming that it will exist, but it’s six of one and half a dozen of the other: if this method fails, urls would also be nil, and if there’s no user library you’re slightly stuffed anyway. At least the try! alerts you to the fact that this might go wrong, and there’s no doubt that you’re only interested in the one true location of the user’s library.
Definitely don’t do this:
Following an online course I picked up in a bundle, which frequently has some good tips and tricks, but which populates a table with a model consisting of a dictionary containing, instead of objects, another dictionary with a [String: [AnyObject]] signature, e.g. [CEO: [“Jane”, “Frances”, “Doe”, “43”]]
I *like* the idea of using a dictionary with a computed array of keys [here: ‘keys’] in the datasource, this makes computing the section titles and number of items in section very easy indeed. (For NSTableView with its plain index, this will not work without further adjustments. Guess how I fell into this particular rabbit hole.)
So, of course, if you want to use the first name in your table, you need to use allEmployees.keys[indexPath.row]]! as? String and…
… yes. Very soon we’ll get to middle names, which people might treat as optional, which shortens the array of items, and which makes [CFO: “Johnny”, “Appleseed”, “54”]’s last name “54”, or rather nil, because an Int is not a string.
Don’t do that. The year is 2017 – ok, it probably was 2016 when this was recorded and maybe even – gasp – 2015, and we have a modern, typesafe language with good OOP capabilities. This is the type of error that Swift easily helps you avoid… if you let it help you.
I’m annoyed that an otherwise good beginner’s resource which I would have liked to recommend for its thoroughness in other aspects disqualifies itself so badly: it’s not easier for beginners to! force! unwrap! everything! and to count items in arrays and pray that the wanted item exists or that they typed the key correctly.
Them’s lousy habits, and I cannot in good faith support a source that has such blatant disregard for the language it is working in, because it is working _against_ Swift.