Links

Functional Programming

Notes

ReactorKit

  • When binding an action, it is possible to manipulate the source stream (that’s usually RxCocoa), like this example.
  • Actions can have a payload.

Operators

flatMap and flatMapLatest

    Observable<String>.from(["😍", "😎"]).flatMapLatest { (str) -> Observable<String> in
        return Observable<String>.from(["\(str)1️⃣", "\(str)2️⃣", "\(str)3️⃣"])
    }.debug("🔴").subscribe().disposed(by: disposeBag)

produces:

2019-04-14 11:31:38.056: 🔴 -> subscribed
2019-04-14 11:31:38.060: 🔴 -> Event next(😍1️⃣)
2019-04-14 11:31:38.060: 🔴 -> Event next(😎1️⃣)
2019-04-14 11:31:38.060: 🔴 -> Event next(😎2️⃣)
2019-04-14 11:31:38.061: 🔴 -> Event next(😎3️⃣)
2019-04-14 11:31:38.061: 🔴 -> Event completed
2019-04-14 11:31:38.061: 🔴 -> isDisposed

Changing flatMapLatest to flatMap will print all events for 😍:

2019-04-14 11:36:22.624: 🔴 -> subscribed
2019-04-14 11:36:22.627: 🔴 -> Event next(😍1️⃣)
2019-04-14 11:36:22.628: 🔴 -> Event next(😍2️⃣)
2019-04-14 11:36:22.628: 🔴 -> Event next(😎1️⃣)
2019-04-14 11:36:22.628: 🔴 -> Event next(😍3️⃣)
2019-04-14 11:36:22.629: 🔴 -> Event next(😎2️⃣)
2019-04-14 11:36:22.629: 🔴 -> Event next(😎3️⃣)
2019-04-14 11:36:22.629: 🔴 -> Event completed
2019-04-14 11:36:22.629: 🔴 -> isDisposed

See how 😎1️⃣ is emmitted asynchronously, before 😍3️⃣

takeUntil

Returns the elements from the source observable sequence until the other observable sequence produces an element. Or, from RxMarbles: discard any items emitted by an Observable after a second Observable emits an item or terminates. See example.

withLatestFrom

TODO

Other notes

  • ..the most obvious way to stop a completed event is single.concat(Observable.never()) source

Summary

Subjects

Subjects act as both an observable and an observer. You saw earlier how they can receive events and also be subscribed to. The subject received .next events, and each time it received an event, it turned around and emitted it to its subscriber.

Actually, every subject type, once terminated, will re-emit its stop event to future subscribers. So it’s a good idea to include handlers for stop events in your code, not just to be notified when it terminates, but also in case it is already terminated when you subscribe to it.

Because it wraps a behavior subject, a ==Variable (BehaviorRelay)== is created with an initial value, and it will replay its latest or initial value to new subscribers. In order to access a variable’s underlying behavior subject, you call asObservable() on it. Also unique to Variable, as compared to other subjects, is that it is guaranteed not to emit an error.

You’d like to add a PublishSubject to expose the photos being selected. However, you don’t want to necessarily make the subject publicly accessible, as that would allow other classes to call onNext(_) and make the subject emit values. You sometimes might want to do that, but not in this case:

fileprivate let selectedPhotosSubject = PublishSubject<UIImage>()
var selectedPhotos: Observable<UIImage> {
  return selectedPhotosSubject.asObservable()
}

Examples of usage

  • You might use a publish subject when you’re modeling time-sensitive data, such as in an online bidding app. It wouldn’t make sense to alert the user who joined at 10:01 am that at 9:59 am there was only 1 minute left in the auction.
  • Behavior subjects are useful when you want to pre-populate a view with the most recent data. For example, you could bind controls in a user profile screen to a behavior subject, so that the latest values can be used to pre-populate the display while the app fetches fresh data.
  • For example, on a search screen, you may want to show the most recent five search terms used. This is where replay subjects come in.