Today I’ll tell you about an
Action type that is available in ReactiveCocoa 4.
Action is pretty straightforward, It takes input, does some work and returns output. Moreover, it can fail and provide us with an
Error type. Let’s look at creation of a simple
action that takes
Int as an input and returns
NSError if it fails.
How do we execute it? In order to do that we have to perform two steps.
Apply method will return a
Action's output as value (
String) and error of
ActionError is an enum that can be either
ProducerError is a wrapper around error type that specify in our
Actual execution happens when we start a
Signal from received
SignalProducer. If we don’t do it, nothing will happen.
observer.sendCompleted() part in our action’s
SignalProducer? It is really important, in fact we need to provide any terminating
Event when we want to finish executing our
Action. If we do not do that, any
Signal started from
SignalProducer will immediately receive
NotEnabled error and we won’t receive any values.
Reveived output: “
1 - Number is 5” and “
2 - NotEnabled”.
We receive this output because of the fact that when we try to execute our action second time, our first execution hasn’t completed yet.
Beside observing single execution of an
Action, you can also observe
Action itself and you’ll receive values that come from each execution. Prepare for a fun part now. There are three ways to observe
Action's values. You can observe
Action's errors and
What’s the difference? Let’s have a look.
Value: Next Number is 5” and “
Our values signal is of type
Signal<Output, NoError>, so you won’t get any errors here. If any terminating
Event occurs during
Action's execution, you’ll receive
Error: Next Error Domain=1 Code=1 "(null)"” and “
Errors’ signal is of type
Signal<Error, NoError> so you can focus on observing errors that occur during
Action's execution. Keep in mind, that you don’t use
observeFailed method to observe errors, as they come with
NEXT events. After
Action's execution is finished, signal will receive
Event: NEXT NEXT Number is 5”, “
Event: NEXT FAILED Error Domain=1 Code=1 ("null")” and “
Third option is to observe signal of ALL
events. This signal is of type
Signal<Event<Output, Error>, NoError>. It means, that you will receive ALL
events as next values, even terminating.
I have to say that this output is a bit confusing. What is “
Event: NEXT NEXT Number is 5”? Why do we get double
NEXT here? Let’s go step by step here.
Let’s look at
SignalProducer implementation. First thing that we send is
observer.sendNext("Number is \(number)") It will send a
NEXT event with a
Our event’s observer receives
Next events with
Next event from our action. That’s why we get “
NEXT NEXT”. Next event that is sent is “
observer.sendFailed(NSError(domain: "1", code: 1, userInfo: nil))”. As previously, our
Failed event comes to
event's observer as
Next event. That is why we get “
NEXT FAILED”. After this terminating event, a
COMPLETED event is sent to our
event's observer indicating that execution has finished.
I hope that this made
Actions clearer to you! See you next time.
This article is cross-posted with my my personal blog.