Errata for SwiftUI by Tutorials, 3rd Edition

Just finished Chapter 9,
In the middle of the chapter, the book asked me to add following line to PracticeView.swift

@State static var numberOfAnswered: Int = 0

and add following line to ChallengesViewModel.swift

var numberOfAnswered: Int { return correctAnswers.count }

The problem is I am using the stater project from Chapter 7(it seem the book allow this), and if you look at the provided stater project of Chapter 7, those two lines are somehow already there:
PracticeView.swift: line 51
ChallengesViewModel.swift: line 75

In Chapter 9’s stater project, those two lines are not there though.

Chapter 6, Section 6.4, just before “Styling the Button”: We are instructed “Next, use the environmentObject modifier on the RegisterView instance to inject it:”. This is very confusing (to me), and is compounded by the fact that most of the code given to be added seems superfluous. I ended up with the following as a best guess of what was intended:

var body: some Scene {
    WindowGroup {
        RegisterView(keyboardHandler: KeyboardFollower())
            .environmentObject(userManager)
    }
}

Chapter 6, Section 6.4: The “Profile” group in the Starter project is empty. Again, I stole the required files from the Final project.

Chapter 6: Submitting the form

  1. minor typo: “Open it, find and add these property and initializer to KuchiApp:”
  • should be “this property” or “these properties”
  1. Piggy-backing off of @fischej 2 comments up; I was also confused by injecting the modifier. It seems that there’s a code snippet to embed the whole thing in a window.rootViewController and UIHostingController but these things are never mentioned/explained preceding nor after said code snippet. The existing code before this snippet is just returning a RegisterView(keyboardHandler: KeyboardFollower()) which is confusing. Even the finished project doesn’t have this code snippet in there.

Chapter 6: Styling the button

In the button styling code, the steps describing what’s happening afterwards does not include a description of why .resizable() is needed between steps 1 & 2. When I comment out or comment in that line I don’t really see any visible difference in the checkmark which feels unclear to me why it’s needed.

Ch. 11.3, in the explanation for the drag gesture.

I think there’s both an error and an omission here. The text to which I’m referring says:

You’re using -1000 and 1000 as the decision markers for whether the user selected left or right during the drag, and that decision is being passed into the dragged closure.

I believe the error is that the “decision markers” are instead -100 and +100 (not 1000). The omission is an explanation for what the 1000 (+ and -) values are used for. I believe those assigned offsets are what cause the card to “disappear” after being dragged past the decision marker point(s).

P.S. Haven’t seen any comment on this thread from any RW representative for over two months. I hope those of us trying to help improve the product here aren’t just whistling into the wind. :slight_smile:

hi Jeff! thanks to you, @pantsz and @wikea1 for posting these issues. We’ll refer to this thread when we update the book.

actually, Bill Morefield replied to you 25 days ago :wink:

My error. I didn’t know Bill was on staff.

Bill wrote the testing chapter and the section on animations (Mountain Airport)

Chapter 15 example project crashes when entering the award page because flightNavigation is not created in @main
Here is code that works

@main

struct MountainAirport: App {
let flightNavigation: AppEnvironment = AppEnvironment()
var body: some Scene {

WindowGroup {

WelcomeView().environmentObject(flightNavigation)

}
}
}

Just finished Ch 19. There are two problem I discovered:

  1. In the middle of the chapter, the code after this sentence “This change allows GenericTimeline to accept View values as dependencies. With that, update the contents of GenericTimeline to the following:”, under //2, the body of init(flights:content:) is missing.

  2. Referring makeUIView(context:) and updateUIView(:context) as makeUIViewController(context:) and updateUIViewController(:context:), probably forgot to update after the API name changed?

Also, the progress time return by flightTimeFraction(flight:) always return 0.0, making the Showing flight progress section confusing, probably because there’s something wrong with the provided flight data, I didn’t look at the detail though.

Honestly, I think these problems should not appear if you have gone through the chapter yourself, I hope your team put more effort on this aspect.

Ch 19 section animating from state changes does not work as instructed. I see on iPhone 11 Pro simulator that the full window expands from the upper left to the lower right.

Xcode Beta 13 and Swift 5.5 Ios 14

If you replace the code on 492 with
.onAppear {
//withAnimation(Animation.default.delay(0.5)) {
showBars = true
//}
}
Then it displays as advertised or something similar as I had moved passed this when I realized what the problem was.

Ch. 13.9:

The instructions read:

While here, change the First Flight button to show this value when present. Replace the code for the Button before the Spacer with:

When I initially posted this, I was confused by the instruction to replace the code and thought surely it must mean add. However, now I’m not so sure. Let me just say that the sequence of instructions from 13.5 through 13.9 left me very confused, and with a non-working product. It certainly may be just me, but when this chapter is revised, please walk through (or better yet, have someone else walk through) these steps and see if they can follow the instructions and end up with the desired product. I don’t think they will end up with the following, but perhaps so, or perhaps this is not actually the desired result. It appears to work, and does produce the screen in the screenshot at the end of 13.9.

Contents of my VStack in WelcomeView.swift:

NavigationLink(
    destination: FlightStatusBoard(flights: flightInfo.getDaysFlights(Date()))
) {
    WelcomeButtonView(
        title: "Flight Status",
        subTitle: "Departure and Arrival Information"
    )
}
if let id = lastFlightInfo.lastFlightId, let lastFlight = flightInfo.getFlightById(id) {
    NavigationLink(
        destination: FlightDetails(flight: lastFlight),
        isActive: $showNextFlight
    ) { }
    Button(action: { showNextFlight = true }) {
        WelcomeButtonView(
            title: "Last Flight \(lastFlight.flightName)",
            subTitle: "Show Next Flight Departing or Arriving at Airport"
        )
    }
}
Spacer()

(Replace this first paragraph with a brief description of your new category. This guidance will appear in the category selection area, so try to keep it below 200 characters.)

Use the following paragraphs for a longer description, or to establish category guidelines or rules:

  • Why should people use this category? What is it for?
  • How exactly is this different than the other categories we already have?
  • What should topics in this category generally contain?
  • Do we need this category? Can we merge with another category, or subcategory?

Ch. 17.7, last code modification before 17.8:

The instructions read

Add the following method after the foregroundColor(_:) call:

The last file modified was FlightTimeHistory.swift, but this modification needs to go in HistoryPieChart.swift. There is no indication in the text that the target file for modification has changed.

Ch. 19.3 in Using a ViewBuilder:

The following code does not compile

// 2
init(
  flights: [FlightInformation],
  @ViewBuilder content: @escaping (FlightInformation) -> Content
)

Error is Initializer requires a body. I gave it one, and the error disappeared. Moving on


[Confirmed: the next time this code is used in the text, the initializer body is given.]

1 Like

Ch. 21.2:

The file MountainAirport.entitlements is in the MountainAirport project files in the Starter folder. It is not excluded from the “copy these files” instructions, nor are we instructed to delete it, but it does not appear in the “your Project Navigator should look like this” screen shot.

An update on this non-issue: it looks like it’s a bug in both UIKit and SwiftUI affecting the toggle control. A discussion is available here