Intermediate Combine

Apr 13 2021 · Swift 5.3, macOS 11.1, Xcode 12.2

Part 1: Intermediate Combine

02. Sharing Resources

Episode complete

Play next episode

Next
About this episode
Leave a rating/review
See forum comments
Cinema mode Mark complete Download course materials
Previous episode: 01. Networking with Combine Next episode: 03. Managing Backpressure

Get immediate access to this and 4,000+ other videos and books.

Take your career further with a Kodeco Personal Plan. With unlimited access to over 40+ books and 4,000+ professional videos in a single subscription, it's simply the best investment you can make in your development career.

Learn more Already a subscriber? Sign in.

Heads up... You've reached locked video content where the transcript will be shown as obfuscated text.

In Combine, publishers are usually structs, and therefore pass by value throughout your code, copying the publisher each time it's passed round. Once it receives a subscription, those individual publishers will do the only thing they can, start its work and deliver values. But what if you want to pass around the publisher by reference instead? This is where the share operator comes into play. It returns an instance of publisher.share and shares the upstream publisher with any subscribers that come after it. It will subscribe to the upstream publisher once with the first incoming subscriber. All other subscribers get values relayed to it by the publisher.share object. Know that there is no sense of buffering or replay involved, new subscribers will only give values admitted after they have subscribed. If a new subscriber comes in after the publisher has completed, it only receives the completion event. Let's take a look at that in an example. Just like in the previous examples, make a subscription on a URLSession.shared instance and use a dataTaskPublisher for operator to get data from raywenderlich.com. Use the map operator to grab the data part of the to bool from dataTestPublisher for, add a print operator to output shared to the console, and then add the share operator. At this point, the pipeline is waiting for the initial subscription to share, to take place, add that via a sink subscriber and have it output that subscription1 was received. This sink subscriber is now subscribed to the upstream publisher via the share operator. Add another sink subscriber. Run this playground. Subscription1 is actually what triggers work. The network request to take place in the publisher. The second subscriber however just gets information relayed to it by the share operator. Note that in the console output, only one instance of shared received value is seen. This is where subscription1 connects to the publisher. There is no corresponding requests from subscription2 since it simply gets the relayed information and doesn't make a formal connection. What if the second subscriber comes after the request has completed? You could simulate this case by delaying the second subscription. The share operator you just learned about is great for cases where subscribers get connected to the pipeline over time and don't care about the data that was admitted before it connected. But what if you want to wait until all of your subscribers are in place before starting to publish? That's where the multicast operator can help. The unique quality of multicast is that the publisher it returns is a connectable publisher, which means it won't subscribe to the upstream publisher until you call connect. This leaves you time to set up all the subscribers you need before letting it connect to the publisher. Let's look at this in an example. Let's modify the example you wrote when learning about share. Prepare a PassthroughSubject that takes in data and emits URLError if things go wrong. Prepare a multicasted publisher using the shared property of URLSession, and use a dataTaskPublisher to connect to raywenderlich.com. Use map to grab the data property from the to bool, add a print operator to see what the pipeline is doing, and then call the multicast operator with the subject you just made. Now make two subscriptions to the shared or multicasted publisher via sink subscribers. Use the receiveValue closure to output a statement to the console stating that the subscription has been received. Now with the subscribers in place, instruct the multicasted publisher to connect to its upstream publisher with connect. Finally, tell the subject to send empty data as a test to see that both subscriptions received data. Run this in the playground, and you can see that both subscribers get the empty data.