Group Group Group Group Group Group Group Group Group

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

Creating this fresh topic to catch any typos and bugs in the 1st Edition of Combine: Asynchronous Programming with Swift (v1.0.3)

The old topic can be read here: https://forums.raywenderlich.com/c/books/combine-asynchronous-programming-with-swift

1 Like

I read Chapter 3 and found it strange that after the replaceNil operator I had to do map with force unwrapping.

It turned out that this is because replaceNil has two implementations for Publishers.Sequence.

_ = Just<Int?>(1)
    .replaceNil(with: 2) // Publishers.Map<Just<Int?>, T>
    .sink(receiveValue: { (value: Int) in
        print(value)
    })

_ = [1, nil, 3]
    .publisher
    .replaceNil(with: 2) // Publishers.Sequence<[Publishers.Sequence<Elements, Failure>.Output], Failure>
    .sink(receiveValue: { (value: Int?) in
        print(value)
    })

_ = [1, nil, 3]
    .publisher
    .replaceNil(with: 2) // Publishers.Map<Publishers.Sequence<[Int?], Never>, T>
    .sink(receiveValue: { (value: Int) in
        print(value)
    })

Hi, @sever7! I’m reaching out to the team to get a response for you. Thanks for being a reader. Hold tight!

Best,
Manda Frederick
Managing Editor, Razeware

Hey @sever7 :slight_smile:
I’m a bit confused about the question. I think the confusing thing in that chapter is the diagram.
When you do Publisher<Int?>.replaceNil(with: 1) you’ll get a Publisher<Int>, and not Publisher<Int?>.

Basically it means that in this diagram, you’ll want to see 1, 2, 3 in the output row:

Definitely something we’ll address. Does that answer your question?

When using a Sequence publisher (e.g. [1, nil, 3].publiser.replaceNil(with: 2)), it does seem like you get back an Optional, but this seems like a wrong behavior (or possibly even a bug). I’ll file a feedback/question regarding this with the Swift compiler team itself to get some clarification.

Thank you!
Shai.

1 Like

Hello @freak4pc
Thank you for the detailed answer

I was confused by the fact that the book said that Publishers.Sequence<[Int?], Never> the replaceNil operator will send an Optional<Int>.

But I found that Publishers.Sequence<[Int?], Never> there are two replaceNil methods and one of them just sends the unwrapped Int.

The correct operator can be called by specifying the expected type .sink(receiveValue: {(value: Int) in }

_ = [1, nil, 3]
    .publisher
    .replaceNil(with: 2) // Publishers.Map<Publishers.Sequence<[Int?], Never>, T>
    .sink(receiveValue: { (value: Int) in
        print(value)
    })

This is exactly what I’m saying - that basically that makes no sense, and seems like a bug in Combine. If I do replaceNil and still get an optional value, I didn’t do much in regards to the value guarantees.

1 Like

@freak4pc thanks for the answer :smile:

Minor: V1.0.3 Chapter 15, Page 293 – RenderView -> ReaderView.

Full sentence: “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.”

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,