Rx
Links
- 2021.03 How to bind button taps from custom cells to your view model
- 2021.01 RxSwift: Deep Inside FlatMap
- 2020.09 5 stranger things you can do with Timelane - Marin Todorov
- 2020.02 RxSwift, Observables, and Core Data Uses an
NSFetchedResultsController
to create an observable. There’s a similar article using Combine - 2019.08 Guarantee Rx memory leaks absence
- 2019.03 Integrating RxSwift Into Your Brain and Code Base (part 1, part 2) Rx-ify a traditional project
- 2019.02 Anatomy of an RxSwift View Model
- 2019.01 ⭐️ RxSwift and Retrying a Network Request Despite Having an Invalid Token Explains the steps to create a JWT mechanism & test it
- 2018.09 The easy way to refresh session token of Auth0 with RxSwift and Moya
- 2018.01 Immutable CoreData with RxSwift - iOS Dev Scout (video, 42’)
- 2017.11 ⭐️⭐️ RxSwift Deep Cuts Goes deep into memory management, schedulers and the internals of
Observable
s (video, 40’) - 2017.06 Top mistakes in RxSwift you want to avoid
- 2017.04 Managing State with RxJava by Jake Wharton (video, 52’)
- 2017.05 UIKonf 2017 – Day 1 –Thomas Visser – Reactive Programming From Scratch
- 2017.03 Learn & Master ⚔️ the Basics of RxSwift in 10 Minutes
- 2016.12 ⭐️ RxSwift Primer (3 parts) Goes from MVC to an Rx-based aproach, getting rid of local state
- 2016.11 Thinking in RxSwift
- 2016.09 The introduction to RxSwift you’ve been missing
- 2016.02 RxJava- Understanding observeOn() and subscribeOn() Very good explanation of concurrency (also refers to backpressure)
Functional Programming
- 📺 dotSwift videos
- Using Combine an intermediate to advanced book, focusing narrowly on how to use the Combine framework
- Introduction to Rx
- 📺 Functional Swift Youtube channel
- The best FRP iOS resources. Collection of many videos, articles etc
- 2019.02 An Introduction to Functional Programming in Swift
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.