RxSwift
Observables
In this story, We will learn what is observable and why it is there? If you like to read the introduction for this, please read here.
Observables are asynchronous. They produce events over some period of time, this process is also referred to as emitting. The produced events are the type of Event<Element>(an enum), which may contain any values, integers, custom types, taps, gestures, etc. All the values are obtained through the next case by its associated value(of type Element). when the observable terminates by successfully(i.e emitting all the values, none left to emit further), the event is obtained through completed case. incase of on error termination, that event is obtained through its error case, with that error as an associated value. Once the observable emits either complete or error events, it won’t emit any new next events.
Observable<T> class produces the sequence of events that carry immutable data of type T. So other classes can subscribe to this observable, can work with the emitted data.
Observables are very important in RxSwift. In RxSwift every thing is a sequence or that can work with a sequence.
→ Life-cycle of an Observable :
An observable can terminate either by successfully(emitting all the values, nothing left for further) or by getting an error. In the following image, elements like {a,b,c,d,e}, {1,2,3,4} are emitted in a sequence with some time in between them. This time we can refer as the life cycle of that observable.
Here the following arrows represents the time. Over the time , you can see the elements here characters a to e , a1, b1,b2…e4 and integers 1 to 4, emitting over until they terminate. This time period is called as life cycle of an observable, and it is shown as a vertical bar on the time arrow. Once the observable has terminated(either successfully or with error), it can no longer emit anything.
When the observable finishes emitting all elements, it can terminate with completed
event. Sometimes there are chances something to go wrong in order to emit the new elements, in that cases it terminates with error
event, with the description of error(as Error object) as its associated value.
→ Creating an Observables :
There are 3 type methods( just
, of
, from
) which we can call on type Observable
itself, to create an observable. Those methods named aptly, for example just
method create an observable for one element which we pass into that as parameter.
→ Subscribing to Observables :
In Rx, we call the procedure of observing an observable is as Subscribing
We call the method subscribe
on Observable type, to observe the emitted events and work with them. An observable won’t send events until it has a subscriber. The method subscribe
has many overload variants with optional closures which are passed by like (next, error, completed, disposed) (Event -> Void) types and subscribe returns a Disposable.
Event has an optional property called element
which gives the associated value which is emitted by .next. In case of other events, the element
will be nil.
→ Disposing & Terminating Observables :
As said before an observable doesn’t do anything until it receives a subscription. It’s the subscription that triggers an observable to begin emitting events, up until it emits an .error or .completed event and is terminated. We can cancel the subscription by calling dispose() on it. After you cancel the subscription or dispose of it, the observable will stop emitting events.
So far, we’ve created observables by calling specific methods like just, of , from, etc. Another way to specify all events that an observable will emit to subscribers is by using the create operator.
The create operator takes a single parameter named subscribe. it defines all the events that will be emitted to subscribers. The subscribe parameter is an escaping closure that takes an AnyObserver and returns a Disposable. AnyObserver is a generic type that facilitates adding values onto an observable sequence, which will then be emitted to subscribers.
Example :
Creating RxSwift like Observables with the help of KVO & KVC :
To know about KVO & KVC mechanism, please check this article.
- For events, we can use the same Rx Event type, like this
- Define Protocols, for the type confirmations
- Define the KVO observer class, which can observe the KVO changes, with the help of key-path.
- Lastly Define an KVOObservable class, which can be initialised with the object of type
NSObject
and key-path to be observed.
Finally we can use the above defined objects to consume the changes for the required properties by subscribing to our custom observables: