Creating this topic to catch any typos and bugs in the 2nd Edition of UIKit Apprentice.
In page 29 (Chapter 1: Introduction â What you need):
(earlir than Big Sur 11.3 or earlier)
earlir
should be earlier
, although I suspect you only wanted one of those two.
In page 30 (Chapter 1: Introduction â Xcode):
If youâre look at an article or book that predates Swift, itâs seriously out of date.
look
should be looking
.
Chapter 29. Maps
There should be mentioned that thereâs need for checking of CLLocationManager().authorizationStatus if the user taps on the âMapâ tab right after the app loads
/ the authorizationStatus is checked only in getLocation() in CurrentLocationViewController /.
Maybe solution not to be included in the chapter, but still to be considered a possible bug.
Chapter 29. Maps
We should check in func region(for:)
if the distance between top left and bottom right is too small (or 0, for example in case of several tags all in one location), or else the span is (0,0) and the map is zoomed-in when showLocaitions is pressed.
if ((topLeft.latitude - bottomRight.latitude) * 111_139 < 100) && ((topLeft.longitude - bottomRight.longitude) * 111_139 < 100) {
region = MKCoordinateRegion(center: center, latitudinalMeters: 1000, longitudinalMeters: 1000)
} else {
let extraSpace = 1.2
let span = MKCoordinateSpan(latitudeDelta: abs(topLeft.latitude - bottomRight.latitude) * extraSpace,
longitudeDelta: abs(topLeft.longitude - bottomRight.longitude) * extraSpace)
region = MKCoordinateRegion(center: center, span: span)
}
chapter 5, section 1 âgetting the differenceâ - under Algorithms:
However, in the programs that you write, youâll probably have to come up with a few algorithms of your own at some time or other.
I would write; âat some time or anotherâ, or âsome time or otherâ. But, to me at some time or another sound the most right.
Chapter 32:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cellIdentifier = "SearchResultCell"
var cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier)
if cell == nil {
cell = UITableViewCell(style: .default, reuseIdentifier: cellIdentifier)
}
cell.textLabel!.text = searchResults[indexPath.row]
return cell
}
While âdequeueReusableCell(:withIdentifier:)â returns a UITableViewCell?, in case cell is nil, the cell allocated from within the if statement is a non optional UITableViewCell.
if Im understanding correctly, after the âifâ statement the cell object might be an optional or not depending on the way it was allocated.
The compiler treats the cell object as an optional, as a result these lines will not compile:
âcell.textLabel!.text = searchResults[indexPath.row]â
âreturn cellâ
We cant unwrap the cell object safely because at running time theres a possibility that it might not be an optional.
After following the tutorial further more, it would seem that in chapter 33 this very bit of code was introduced as it were supposed to be:
let cellIdentifier = "SearchResultCell"
var cell: UITableViewCell! = tableView.dequeueReusableCell( withIdentifier: cellIdentifier)
if cell == nil {
cell = UITableViewCell(
style: .subtitle, reuseIdentifier: cellIdentifier)
}
Here the cell is not type inferred and is unwrapped at creation.
Chapter 32âs version of the code should be updated to this version.
Missing images in UIKit Apprentice 2nd Edition (Section 1, Chapter 2)