On Chapter 3, page 80, for the flatMap
section
Shouldn’t the correct output be like the following?
Hi, I'm Charlotte!
Hi, I'm James!
On Chapter 3, page 80, for the flatMap
section
Shouldn’t the correct output be like the following?
Hi, I'm Charlotte!
Hi, I'm James!
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.
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.
Hi folks, here’s what I got:
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.DispatchTimer
, the markers are 5 and 6, but the text refers to them as 1 and 2receive(subscriber: S)
method, the markers are 7, 8 and 9, but the text refers to them as 1, 2 and 3Thanks,
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).
In Chapter 2: Publishers and Subscribers:
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.
"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.
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
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.
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?”.