Reactive Programming in iOS with Combine

Feb 4 2021 · Swift 5.3, macOS 11.0, Xcode 12.2

Part 2: Transforming & Filtering Operators

07. Transforming Operators

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: 06. Introduction Next episode: 08. More Transforming Operators

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.

The first type of operators we'll focus on are transforming operators. This style of operator is the most common and is used to manipulate values coming from publishers into a format that's suitable for subscribers downstream. As we discuss this type of operator, you'll see many similarities and differences with operators from the Swift standard library such as map and flat map. Let's start with the collect operator. This operator takes a stream of individual values from a publisher and turns them into an array of values. The marble diagram you see on screen here demonstrates how this operator works. The top line represents the publisher, the box in the middle represents the operator which we've labeled collect, and the bottom line represents the subscriber or more specifically what a subscriber would receive from the operator. Here the individual values one, two, and three have been collected into an array of integers, with one, two, and three inside it. Remember that since operators can act as subscribers as well as publishers, the subscriber represented by the bottom line could be another operator. Inside the starter playground for this part of the course add this code. This set of code initializes the array of strings, creates a publisher from it, and then subscribes to the publisher with a sink subscriber. If you run it now you'll see that it simply outputs the array elements one by one. There's no operator in the pipeline, so let's add a collect operator. You'll see this code block style repeated throughout the course, a publisher, one or more operators with a sink subscriber and a store at the end of the pipeline. Running the playground now you can see that the values are collected into a single array, which is received by the sink subscriber and printed to the console. You may have noticed that there is nothing that restricts the number of items that the collect operator can work on, so be careful with large datasets, you could run into memory issues. If you want to limit the number of items that get collected, you can use something like collect two, let's update our code and see what happens. Since collect is now limited to only collect two items, several arrays get generated, including a partial one with only one member since the publisher ran out of values and collect did the best it could with the values given. Sometimes you'll want to transform the incoming data from a publisher in some way before sending it on to a subscriber. And that's where map comes into play. The marble diagram shows that values coming in to the operator represented by the dollar sign zero and the closure body of the operator get manipulated and sent to the subscriber. For every value sent by the publisher, there is a corresponding mapped value sent to the subscriber. Let's look at that in a playground. Add the following to your playground. Here you've freed a number format which will spell out the numbers into a string. Then you have an array of numbers and then generate a publisher from it. Finally, you insert a map operator between the publisher and the sink subscriber. The body of the map operator is a closure that takes in the past in value and processes it through the number formatter. When you run the playground you see a list of values, one for each value in the original array representing the string versions of the numbers. What happens if you experience a nil in your upstream values? You could use something like the no coalescing operator to provide a default, but you can use an operator instead, replace nil in fact. The marble diagram here shows that anytime a nil is encountered in the publisher stream, it's replaced with the values specified in the operator's closure. Let's take a look at that in an example. Build the usual publisher operator sink block with an array of strings, one of which is a nil adding as the publisher. For the operator use replaceNil with and pass any string with a dash character as the argument. Running the pipeline shows that the nil has been replaced with a dash giving you result of A dash C. Note that the playground shows a warning. After calling replaceNil, we can safely assume that each of the values is not Nil, so we can explicitly unwrap it before printing it using a simple map before the sink statement. And now the warning is gone. ReplaceEmpty handles the case where the publisher fails to emit any values before completing, in this case, replaceEmpty inserts the specified value into the pipeline for the downstream consumer to use. Note here that your publisher must send a completion event for this operator to work, otherwise it doesn't know if the publisher is done emitting values. For this example use a special publisher empty, which has an int value and never returns an error. The operator used in our publisher operator sink block is replaceEmpty with an argument of one. (indistinct) the playground, you see that the one gets inserted into the pipeline and emitted, it becoming that operator out, no values get emitted. In this episode, we took a look at some of the basic transforming operators Combine has to offer, collect takes individual values from a publisher and transforms them into an array of those values, and map transforms values from the publisher based on a closure you pass into the map operator sending those transformed values downstream. replaceNil and replaceEmpty replace Nils and empty publishers with specify values. In the next episode, we'll up the complexity a bit and introduce scan and flat map into your Combine tool belt.