Errata for Swift Apprentice 4th Edition

Creating this topic to catch any typos and bugs in the 4th Edition of Swift Apprentice.

Many readers like to cut and paste code from the PDF as they go. This is a great way to learn. Unfortunately there are some bugs in Xcode 10 playgrounds where if you cut and paste in partial code you can get a fatal crash. We are aware of one such case in chapter 10 where code (function signature) is split across two pages. If you cut and paste these in one-by-one, it will crash and you will no longer be able to open the playground. We are informing Apple of this bug via radar. Our workaround (implemented on master) is to add a page break so the code is not split at a funny place.

Hi, I found something make me confusing in Chapter09-strings-challenges-Challenge 3.

I change the function input from “Galloway, Matt” to “,” , then it run failed.

Console show this ( Fatal error: Can’t advance past endIndex)

I wonder if the function could be better to avoid this?

@duckmole The function crashes because indexAfterCommaSpace isn’t a valid index of name in this case. Please let me know if you have any other questions or issues about the whole thing. Thank you!

If you were to place the code in StudentAthlete there wouldn’t be a failedClasses array. The author probably meant what would happen if StudentAthlete were subclassed but he wrote replace. (chapter 14)

In chapter 1, challenge 3, the instructions tell the reader to

Work out what answer equals when you replace the final line of code above with each of these options

But there is no answer constant declared in the previous code block (which also means it can’t be replaced).

In chapter 16 Record is not a structure. In the next paragraph you typed the twice.

In chapter 16 you are not comparing two Record types. You are comparing two instances of type Record. The Apple documentation states it is a static function. I do not understand why the function needed to be static. It aims at comparing instances anyway.

In the first table of chapter 17 it would make more sense to write KeeperKind(keeperOf: .etc) at the right hand side. In the second table you write etc. The second table describes your goal more accurately. The place of the dot can lead to confusion.

In chapter 16 the implementation of hash(into:) is not thoroughly explained :slight_smile:

In chapter 17 is should be emphasized that Cat nor Dog are subclasses of Animal in the Anatomy of generic types section. Later on it becomes clearer that they could be by the way.

The challenge of chapter 17 asks for a private array. Access control is taught in chapter 18.

Sorry for my late reply @duckmole. It is a good point. Handling user input can be a bit tricky as your example shows. A non-safe language like C might let you keep going which can be very bad from a security point of view. (Trapping is what Swift does when you walk off the end of a buffer.)

I think a better way to handle it would be to drop the first two characters since dropping more than there are more characters results in a no-op.

So something like this:

func sanitized(name: String) -> String? {
  guard let indexOfComma = name.index(of: ",") else {
    return nil
  }

  let last = name[..<indexOfComma]
  let first = name[indexOfComma...].dropFirst(2)

  return first + " " + last
}

Thanks again.

StudentAthlete is a subclass of Student. It introduces a failedClasses property and overrides recordGrade(_:) so that it updates that property. It is not a super elegant design but demonstrates the mechanics of inheritance and overriding. Are you thinking of another design? I wasn’t sure what you meant.

Thanks. Looks like it was fixed in the playground but not in the text.

Good catch! In the original version they were structs but because Swift 4 gave us automatic equatable conformance we wanted to something a little more complex were automatic conformance wouldn’t work well.

Originally Swift made you declare == as a global function. (You still can do this and it is perfectly valid, old-school Swift.)

However it is better form to declare an extension with conformance to Equatable and implement it right there. But this is essentially a global function which is why it is declared static.

It is dispatched statically, which means that the function call is resolved at compile time. It would be a compile time error to compare Records and Ints but you could make it work by declaring an == method for those types. It would compile but not be part of equability.

I think some improvement could be made to the text to describe the static requirement.

Thanks. I’ll make sure the author considers that feedback in the next go-around.

Good catch. Thanks for the feedback. I feel like maybe private should be introduced in the chapters on properties. Then it can be explained in more detail with its friends public, internal, and fileprivate in the access control chapter.