RxSwift Subjects
Subjects act as both an observable and an observer. They can receive events and also be subscribed to. Subjects are extremely powerful as they can accept subscriptions and emit events, as well as add new elements onto the sequence.
These are four subject types in RxSwift.
Publish Subject
- Starts empty and only emits new elements to subscribers.
- Publish Subjects are used when you want subscribers to be notified of new events from the point at which they subscribed until the subject has terminated or they either unsubscribe.
In the below marble diagram,
‣ The Topline is the publish subject.
‣ The second, third, and fourth lines are the subscribers.
‣ The upward-pointing arrows indicate subscriptions.
‣ The downward-pointing arrows indicate emitted events.
‣ A, B, and C are the events and the red cross indicates the error.
The first subscriber subscribes after A event, so it doesn’t receive the A event. It does get B and C event.
The second subscriber subscribers after the B event, so it receives the C event.
An Error occurred after event C, so the third subscriber received only an error event. All the subscribers also received the error event.
When a publish subject receives a .completed or .error event, known as a stop event, it will emit that completed or error event to subscribers and it will no longer emit new events.
The Publish subject will re-emit its stop event to all the future subscribers.
Output for above code
Subscriber 1: B
Subscriber 1: C
Subscriber 2: C
Subscriber 1: D
Subscriber 2: D
Subscriber 1: error(genericError("An error occurred!"))
Subscriber 2: error(genericError("An error occurred!"))
Subscriber 3: error(genericError("An error occurred!"))
Behavior Subject
- Starts with an initial value and replays it or the latest element to new subscribers.
- In other words, it replays the latest .next event to new subscribers.
In the above marble diagram,
‣ The Topline is the Behavior subject.
‣ The second, third and fourth lines are the subscribers.
The First subscriber subscribers after event A but before event B, so it gets A immediately after subscription and then B and C as they are emitted by the subject.
The Second subscriber subscribers after event B, so it gets event B immediately after subscription.
After event C, an error event occurred so the third subscriber and any future subscribers will get an error event only.
Note:- You can't create behavior subject without providing a default initial value as it always emits the latest element.
Output for above code
Subscriber 1: DEFAULT - A
Subscriber 1: B
Subscriber 2: B
Subscriber 1: C
Subscriber 2: C
Subscriber 1: D
Subscriber 2: D
Subscriber 1: error(genericError("An error occurred!"))
Subscriber 2: error(genericError("An error occurred!"))
Subscriber 3: error(genericError("An error occurred!"))
Replay Subject
- Initialized with buffer size and will maintain a buffer of elements up to that size and replay it to new subscribers.
In the above marble diagram,
‣ The Topline is the Replay subject.
‣ The second and third lines are the subscribers.
Assume a replay subject with buffer size if 2.
The first subscriber subscribers to replay subject when it had emitted zero events. So it gets elements as they are emitted.
The Second subscriber subscribes after event C, so it get B and C replayed to it as the buffer size is 2.
When using a replay subject, the buffer is held in memory. If you set a large buffer size, it will take up a lot of memory. The developer needs to make sure that the replay subject is used where the use case will only store a ‘reasonable’ number of elements.
Output for above code
Subscriber 1: A
Subscriber 1: B
Subscriber 1: C
Subscriber 2: B
Subscriber 2: C
Subscriber 1: D
Subscriber 2: D
Subscriber 1: Completed
Disposed
Subscriber 2: Completed
Disposed
BehaviorRelay
- BehaviorRelay replaced RxSwift’s Variable as a variable is deprecated.
- It lies in RxCocoa, so you need to import RxCocoa.
- You can add values to BehaviorRelay using the .accept method.
- Relay that emits the most recent item it has observed and all subsequent observed items to each subscribed observer.
In the above marble diagram,
‣ The Topline is the BehaviorRelay.
‣ The second line is the subscriber.
The First subscriber subscribers after event B so it gets event B and events emitted after that.
BehaviorRelay cannot be terminated with .completed or .error event
Output for above code
Subscriber 1: B
Subscriber 1: C
Subscriber 1: D
Subscriber 2: D
Subscriber 1: E
Subscriber 2: E
Subscriber 1: F
Subscriber 2: F
Thank you. I hope this helps!