2 hours to master RxSwift — Part 2: Core concepts
In the example of previous article: 2 hours to master RxSwift — Part 1, we probably saw some code such as subscribe
without any explanation, we will go through some key concepts and principles on the RxSwift.
Observable
Observable is core concept in RxSwift. In RxSwift, an Observable
is a sequence that emits events (values or errors) over time, and notifies its observers(also called Subscribers) when these events occur.
In RxSwift world, arrays, strings, numbers, timers, network requests, and user interface events needed to convert into Observables first before use. An observable can emit a number of events followed by either a completion event (signifying that the sequence has ended) or an error event (signifying that an error occurred).
Subscriber
On the other hand, when events is emitted from Observable
, we need the Subscriber
to receive, which specify who can and will receive those events. This process is callled subscrition
. A similar example in the real world is when we follow a youtuber, we will receive notification once they updated their channel.
The Subscriber has three main methods to deal with events:
onNext
: this is the main one used to handle every emitted element from the Observable.onError
: handles any errors emitted by the Observable, such as network failure, fallbacks and so on.onCompleted
: handles the completion event emitted by the Observable. Once reevied thecompletion
event, theObservable
will NO emit any event anymore.
The Subscriber also has a dispose()
method that can be used to cancel the subscription and stop receiving events from the Observable.
Example of Observable and Subscriber
The following is an example of creating an Observable and Subscriber
import RxSwift
// Create an observable that emits an integer array
let observable = Observable.Observable.from([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
// Subscribe to the observable to receive its emitted values
_ = observable.subscribe(onNext: { value in
print(value)
}, onCompleted: {
print("Observable completed")
})
We will get:
1
2
3
4
5
6
7
8
9
10
Observable completed
With the example above, first create an Observable
emits three integer values. Then subscribe to the Observable and print each emitted value to the console using the onNext
closure. Finally, we print "Observable completed" when the Observable completes emitting values.
Operator
In RxSwift, operators are functions that can “operate” on Observables and return Observables, which will allow us to do some specific task in a simple way. Take the above example, suppose we only want even number, we can simply add a filter
:
let observable = Observable.from([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
// Subscribe to the observable to receive its emitted values
_ = observable
.filter { $0 % 2 == 0 } // filter to even numbers
.subscribe(onNext: { value in
print(value)
}, onCompleted: {
print("Observable completed")
})
We will get the output:
2
4
6
8
10
Observable completed
Beside filter
, there are many operators in RxSwift, each with its own specific functionality, here are some common used ones:
map
: transforms each element emitted by an Observable by applying a function to it.filter
: filters the elements emitted by an Observable based on a predicate.flatMap
: transforms each element emitted by an Observable into another Observable, then flattens the emissions from these Observables into a single stream.merge
: combines multiple Observables into a single Observable by merging their emissions.zip
: combines the emissions of multiple Observables into a single Observable by emitting tuples of corresponding elements.
We will cover more on this in the later article.
Subjects
In RxSwift, the subject is a special type which is a combine of observable
and subscriber
, meaning it can either observed by multiple subscribers
, and also can emit events to others.
There are several types of subjects available in RxSwift, including:
- PublishSubject: doesn’t have an init value, emits only new value to its subscribers
- BehaviorSubject: have an init value, emits latest value to subscribers
- ReplaySubject: emits a buffer of values to new subscribers, so they can receive max buffer size past values before subscription
- AsyncSubject: emits only the final value to its subscribers only after the sequence has completed
// Example of PublishSubject
let subject = PublishSubject<String>()
subject.onNext("test") // No one is listening at this point
let subscription = subject.subscribe(onNext: { string in
print(string)
})
subject.onNext("abc") // test is not printed, only abc
// Example of BehaviorSubject
let subject = BehaviorSubject(value: "abc")
subject.onNext("def") // print out due to this is the latest value
let subscription = subject.subscribe(onNext: { string in
print(string)
})
subject.onNext("ghi") // print out def and ghi
// Example of ReplaySubject
let subject = ReplaySubject<String>.create(bufferSize: 4)
subject.onNext("1")
subject.onNext("2")
subject.onNext("3")
subject.onNext("4")
subject.onNext("5")
let subscription = subject.subscribe(onNext: { string in
print(string)
})
subject.onNext("6")
subject.onNext("7")
subject.onNext("8")
// Example of AsyncSubject
let subject = AsyncSubject<String>()
subject.onNext("Hello")
subject.onNext("World")
let subscriptionOne = subject.subscribe(onNext: { string in
print(string)
})
subject.onNext("!")
subject.onCompleted() // print out ! if onCompleted is called, otherwise no output.
What is Next
In the next article we will have a look at the Observable
in depth.
👉 If you want received more stories like this, please subscribe my channel to get the latest update in time
Originally published at https://needone.app on March 14, 2023.