Errata for Combine: Asynchronous Programming with Swift 1st Edition (v1.0.3)

On Chapter 3, page 80, for the flatMap section

Screenshot 2020-03-25 at 8.55.13 PM

Shouldn’t the correct output be like the following?

Hi, I'm Charlotte!
Hi, I'm James!
1 Like

Chapter 8: “Updating the UI after the publisher completes”

In this section, code is added to update the header when the newPhotos stream completes, but there are no instructions to add trigger this event and the Starter project does not contain it either.

The fix is to add

    selectedPhotosSubject.send(completion: .finished)

On the viewWillDisappear method of the PhotosViewController,

Chapter 4, near the end, the diagram for prefix(untilOutputFrom:).
The green “isReady” dot should be between 2 and 3, in my opinion.

Screen Shot 2020-04-22 at 16.41.38

1 Like

Chapter 4. Diagram for last(where:).
The output will only happen when the publisher completes, so it can’t happen at the same time as drawn. See below how it should be fixed, IMO.

Screen Shot 2020-04-22 at 16.43.11

1 Like

Great pieces of feedback, thanks Jacob ! @apparentsoft

1 Like

Hi folks, here’s what I got:

  • There was, what I think is, an error on Chapter 8, under “Updating the UI after the publisher completes”, there is a step that is missing, sending the completion event, I noticed what was going on by looking a the final project, but I wouldn’t have been able to do this on my own.
  • Chapter 18
    • In the DispatchTimer publisher page (on the Playground), the ‘Foundation’ import is missing.
  • Chapter 20:
    • I had a hard time swiping right on the simulator, I honestly don’t know if it was the lack of dexterity on my end or something else.
    • I decided to try my luck running the app my phone, I changed the Bundle Identifier, the Team and the Provisioning Profile, the app was installed but it crashed, both the final and starter projects crashed, so I could never try the full experience of the app, just left swipes :{
    • Super minor, there is a typo on “Review the data model”, it refers to the CoreData model as Models/ChuckNorrisJokes.xcdatamodeld instead of Models/ChuckNorrisJokes.xcdatamodel (extra d)
  • All throughout the book there were some errors related to the number markers in the code and the numbers in the description, here are some that I caught:
    • Chapter 18
      • In the extension for DispatchTimer, the markers are 5 and 6, but the text refers to them as 1 and 2
      • In the receive(subscriber: S) method, the markers are 7, 8 and 9, but the text refers to them as 1, 2 and 3
      • Something similar happens under “Adding required properties to your subscription”
      • Once again under “Creating your subscription” and “Subscribing to the publisher and handling its inputs”
    • Chapter 20
      • A different, but similar (?) error happens right after the code block under “Extending JokeManagedObject to save jokes”, the text that describes what the code is doing starts with 1, 2, then goes back to 1

Thanks,
Leo

In the Book Source Code and Forums section, the link to download the source code is broken when you click on it. If you copy the whole URL and paste it in the browser, it will 404 because there are encoded spaces (%20).

1 Like

@mandafrederick could you have a look at the download links?

In Chapter 2: Publishers and Subscribers:

  1. under the header Subscribing with sink(_:_:) we add the code to post and the notification and cancel the subscription. Later under Hello Cancellable it says:

Finish the Subscriber example from earlier by adding the following code:

And then has you add the same two lines as before.

  1. There is a typo after the example of "Dynamically adjusting Demand" code:

Most of this code is similar to example you’ve previously worked on in this chapter

Bug: V1.0.3 Chapter 15, Page 285 timer feature fails to work in both my copy and the ‘finished’ project

I’m guessing somethings changed on the iOS side. This book has been batting 1,000 so far and it’s hard for me to believe this didn’t used to work.

My system info:
OS: 10.15.5 (19F96)
Xcode: Version 11.5 (11E608c)
iOS: 13.5
iOS Simulator: Version 11.5 (921.9.1) SimulatorKit 581.9.1 CoreSimulator 704.12.2

It fails in the simulator as well as on my phone for both my version and the ‘finished’ project version in Chapter 15.

Adding the ‘print()’ for tracing like so…

  @State var currentDate = Date()
  private let timer = Timer.publish(every: 10, on: .main, in: .common)
    .autoconnect()
    .eraseToAnyPublisher()
   .print("timer")

Shows the following output in Xcode:

timer: receive subscription: (Timer)
timer: request unlimited
timer: request unlimited
timer: receive cancel
timer: receive subscription: (Timer)
timer: request unlimited
timer: request unlimited
My ‘educated’ guess is you had your JSON ‘polling’ the Hacker News server at one point and this worked. As soon as we get the JSON we close things down causing our timer to get a cancel message and it turns out the lights on us before we even walk into the room. :slight_smile:

Just a guess.

It would be great to get feedback or details on how to fix this going forward. Thanks for a great book!

Cheers

2 Likes

Hi @cupofjoe - some of the underlying code in SwiftUI seems to have changed indeed recently. I had someone report a similar issue related to the timer in this chapter, have a look maybe it’s the same root cause? Errata for Combine: Asynchronous Programming with Swift 1st Edition - #67 by denisblondeau

That fixed it for me! Thanks for the quick response. I was able to ‘print’ and see the timer canceled but I put all of my effort into the PostedBy helper. Never even thought about changing the order in the main view. I’m going to need to read that SwiftUI book now so I understand what’s behind that curtain. :grinning:

Minor editorial fixes:

Chapter 3 - Collecting Values - collect() - last sentence first paragraph:

“To help understand how this and all other operators you’ll learn about in this book, you’ll use marble diagrams.”

Need to either remove “how” or add “work” or (forgive me) “operate” after “book”.


Chapter 3 - Flattening Publishers - last paragraph, last sentence:

"So, before wrapping up this chapter, you’ll learn a couple more useful operating for doing the ol’ switcheroo.”

“operating” should be “operators”

A few other minor editorial fixes:

Chapter 15 - near the end, as keywords and SettingsView are wrapping up:

Remember, adding the keyword to the list here will update the settings model object and in turn, will update the reader view model and refresh RenderView as well.

RenderView should be ReaderView. Thanks!


Chapter 18 - near the end, when adding subscriptions:

let subscription1 = publisher.sink(
  receiveCompletion: {
    print("subscription2 completed: \($0)", to: &logger)
  },
  receiveValue: {
    print("subscription2 received \($0)", to: &logger)
  }
)

subscription1 is printing descriptions for “subscription2” (subscription2 is printing the same)


Chapter 20 - Last sentence of the Note before the Setting Goals section:

However, if the preview rendering fails, of if you’re still running macOS Mojave, you can also build and run the app to a simulator to check out your progress.

“of” should be “or”

I have a question on pg. 204 regarding the handling of dismissing the alert automatically when the currently-presented view controller is dismissed.

 extension UIViewController {
    func alert(title: String, text: String?) -> AnyPublisher<Void, Never> {
        let alertVC = UIAlertController(title: title,
                                        message: text,
                                        preferredStyle: .alert)
        
        return Future { resolve in
            alertVC.addAction(UIAlertAction(title: "Close", style: .default) { _ in
                resolve(.success(()))
            })
            
            self.present(alertVC, animated: true, completion: nil)
        }
        .handleEvents(receiveCancel: {
            self.dismiss(animated: true)
        })
        .eraseToAnyPublisher()
    }
}

Assuming in the currently-presented view controller, we are storing the alert subscription when we present the alert and subscribe to the Future returned.

Pg. 204 says:

This code handles the case when you tie the alert subscription to the currently-presented view controller and that controller gets dismissed itself. This will cancel the alert subscription and dismiss that alert as well.

However, it seems like the receiveCancel closure is strongly referencing/capturing self, so in the case that the controller gets popped or dismissed itself, the controller (and its alert subscription) still won’t get de-init’ed because the receiveCancel closure has a reference of it.

Changing the receiveCancel to capture weak self and self?.dismiss(...) wouldn’t help either, because by the time receiveCancel is invoked due to the VC getting de-inited, the weak self is already nil’ed and dismiss would not get called.

Any idea on how to properly handle this?

Minor typo at Chapter 2 page 41: log output “Example of: Publisher” but that time it should be “Example of: Subscriber” as code piece already:

example(of: "Subscriber") {

Chapter 2 page 45: tell us to add code for subscription cancellation, but that piece of code was already added previously (page 41)

Chapter 4 page 107:

… ignores any values emitted by the publisher until the first time that predicate is met. As soon as the predicate is met, values begin to flow through the operator.

I believe this should be changed to:

… ignores any values emitted by the publisher until the first time that predicate is not met. As soon as the predicate is not met, values begin to flow through the operator.

With this in mind, the text on the following page should be updated. It is treating the predicate ($0 % 5 != 0) as asking “is this divisible by 5?” when the predicate is actually asking “is this not divisible by 5?”.