ReactiveCocoa Operation Methods

ReactiveCocoa Operation Prerequisites All signals () can be processed with operation methods, because all operation methods are defined in . Any class that inherits from gains access to these operation methods. ReactiveCocoa Operation Philosophy RAC uses a Hook pattern. Hook is a technique for changing the execution result of an API (application programming interface or method). - Hook's purpose: intercepting API calls. - Hook's principle: before each API call returns its result, your own method runs first to modify the output. ReactiveCocoa Core Method: The core operation method in ReactiveCocoa is . In fact, the core development pattern in RAC is binding. Traditional development is assignment-based, whereas RAC development should focus on binding — you can bind the desired behavior at the time an object is created, rather than waiting until after assignment. For example: instead of overriding a control's method to display data, with RAC you can bind the data at the moment the control is created. In practice, is rarely used directly. It is a low-level method in RAC, and RAC provides many convenient higher-level methods that wrap it internally. Using Suppose you want to monitor a text field's content and prepend the string "Output:" to every value before it is emitted. Method 1: Append text after receiving the result. Method 2: Prepend text before the result is returned, using RAC's method. - parameter: takes a block that returns a . - is a block type that returns a signal and takes parameters (, ). So the block parameter itself also returns a block. RACStreamBindBlock: - Parameter 1 (): The original unprocessed value received from the signal. - Parameter 2 (): Controls the bind block. If , binding ends. - Return value: A signal. Process the data and return it via this signal. Typically uses — requires manually importing . Steps for using : 1. Pass in a block that returns . 2. Describe a of type as the block's return value. 3. Describe a result signal as the 's return value. Note: handle signal result processing inside . Internals: 1. Calling on the source signal creates a new bound signal. 2. When the bound signal is subscribed to, its is called, generating a . 3. When the source signal emits a value, it is passed to for processing via . 4. returns a signal () with the processed content. 5. Subscribing to retrieves the bound signal's subscriber and sends out the processed content. Note: different subscribers store different s. When reading source code, be careful to identify which subscriber is which. Note: you must manually import to use . - and are used to map the contents of a source signal to new values. For example, you can monitor a text field's content and remap the output to a new value. - : Maps the content of a source signal into a new signal. The signal can be of any type. usage steps: 1. Pass in a block with return type and parameter . 2. is the source signal's content. Use it to do your processing. 3. Wrap the result into a and return it. internals: 0. is implemented using internally. The block's return value in becomes the return value of in . 1. When the bound signal is subscribed to, is generated. 2. When the source signal sends content, is called. 3. internally calls 's block, which wraps the processed data into a signal. 4. The returned signal ultimately serves as the return signal of . 5. Subscribing to 's return signal retrieves the bound signal's subscriber and sends out the processed content. - usage: for example, monitor a text field's content and remap the output to a new value. - : Maps the source signal's value to a new value. - Map usage steps: 1. Pass in a block that returns an object and takes a parameter. 2. is the source signal's content — use it directly. 3. Return the processed content directly. No need to wrap it in a signal. - Map internals: 1. internally calls . The return value from 's block becomes the value in 's block. 2. When the bound signal is subscribed to, is generated. 3. When the source signal sends content, is called. 4. internally calls 's block. 5. 's block calls 's block and wraps its return value into a signal. 6. The returned signal ultimately serves as the return signal of . 7. Subscribing to 's return signal retrieves the bound signal's subscriber and sends out the processed content. Difference between and 1. The block in returns a signal. 2. The block in returns an object. 3. In practice, if the signal's emitted value is not itself a signal, use . 4. In practice, if the signal's emitted value is a signal (signal of signals), use . Summary: use for signal of signals. ReactiveCocoa Combination Operations - Concatenates signals in order. When multiple signals are combined, values are received in sequence. - The next signal is subscribed to only after the previous one completes. If the previous one errors, the next one is not subscribed. - internals: 1. When the concatenated signal is subscribed, its is called. 2. first subscribes to the first source signal (signalA). 3. signalA's is executed. 4. When signalA's sends values, signalA's subscriber's is called and the values are forwarded via the concatenated signal's subscriber. 5. When signalA's sends a completion, signalA's subscriber's is called and signalB is subscribed, activating it. 6. signalB's is executed. 7. When signalB's sends values, they are forwarded via the concatenated signal's subscriber. - Used to connect two signals. The second signal (returned by ) is connected only after the first signal completes. - Note: values from the first signal are discarded when using . - Internals: 1. First filters out values emitted by the previous signal. 2. Then uses to connect the signal returned by . - Merges multiple signals into one. Any signal emitting a new value triggers the merged signal. - All signals are subscribed simultaneously; any response triggers a response. - Internals: 1. When the merged signal is subscribed, it iterates over all signals and subscribes to each. 2. Each signal is subscribed as it is enumerated. 3. As soon as the merged signal is subscribed, all internal signals are subscribed. 4. Any signal emitting a value is immediately observed. - Zips two signals into one. Only when both signals have emitted a value simultaneously are they combined into a tuple and emitted as the zip signal's next event. - Internals: 1. Defining the zip signal automatically subscribes to signalA and signalB internally. 2. Whenever signalA or signalB emits a value, it checks whether both have emitted. If so, the most recent values from each are wrapped into a tuple and emitted. - Combines multiple signals and takes the latest value from each. All combined signals must have called at least once before the combined signal fires. - Internals: 1. When the combined signal is subscribed, signalA and signalB are subscribed internally. Both must have emitted values before the combination fires. 2. The two signals' values are combined into a tuple and emitted. - Aggregation: used when a signal emits tuples. Aggregates the tuple's values into a single value. - Common usage: combine then reduce. - About the : the has as many parameters as there are combined signals. Each parameter corresponds to the value emitted by its respective signal. The 's return value is the aggregated result. - Internals: subscribing to the reduce signal causes to be called each time content is emitted, converting the signal content to the value returned by . ReactiveCocoa Filter Operations - Filters a signal; use it to receive only values that meet a condition. - Each time the signal emits, the filter condition is evaluated first. - The signal continues only when the block returns . - Ignores signals whose value matches the specified value. - Internally calls to exclude the ignored value. - Emits a signal only when the current value is different from the previous value; otherwise the signal is ignored. - Filters out consecutive duplicate values. - Commonly used to avoid unnecessary UI refreshes — only refresh when the data actually changes. - Takes only the first N signals from the beginning. - Takes only the last N signals. Requires the subscriber to call first, since the total count is only known at completion. - Receives values until a specified signal completes (e.g., monitor text field changes until the current object is deallocated). takeWhileBlock - Subscriber receives values only when the block logic returns . - Skips the first N signals (e.g., the first emission is ignored). skipWhileBlock Skips values while the block logic returns . skipUntilBlock Skips values until the block logic returns . - Used with signal of signals. Sometimes a signal emits other signals. retrieves the most recently emitted inner signal from a signal of signals. - Gets the most recently emitted inner signal and subscribes to it. Note: can only be used with signal of signals. ReactiveCocoa Order Operations - Executes this block before executing . - Executes this block before executing . ReactiveCocoa Threading Operations - Switches content delivery to the specified thread. Side effects remain on the original thread. Code in the signal creation block is considered a side effect. - Switches both content delivery and side effects to the specified thread. ReactiveCocoa Timing Operations - Timeout: causes a signal to automatically error after a specified duration. - Timer: emits a signal at regular intervals. - Delays sending . ReactiveCocoa Repeat Operations - Retry: on failure, re-executes the signal creation block until it succeeds. - Replay: when a signal is subscribed multiple times, previously emitted content is replayed. - Throttle: when a signal fires very frequently, throttle can be used to suppress emissions for a period of time, then emit only the latest value after that period ends. - Commonly used to optimize real-time search — prevents excessively frequent requests. Code: All code from this article can be found on my GitHub at .