1
votes

I'm studying RXSwift, and I'm a little confuse about Observables. I've understood the theory, that it can emit events "over time". But, I must initialize it with a value, subscribe, and user that value (which is pointless), but I cannot change the value of that observable later, so, whats the point of saying that it can emit values "over time"??? Can someone clarify it to me? Thanks a lot!

2
There's nothing that says you must initialize them with a value. Observables can return zero or more values before (possibly) completing or failing with a error.Enigmativity

2 Answers

2
votes

It's true that you can't change the value of an Observable directly because that's not the point of having an Observable. In that case you can just return a value and mutate it inline without using observable.

Think of observable simply as a sequence of events ordered by time. On a sequence data structure you're not directly manipulating / mutating what's inside them, what you do normally is to map them into something else, filter the events that you want to exclude based on a certain condition, or combine them with another sequence.

For example, you can map these events which can be described as e(t), with the horizontal line represents the flow of time.

--1--2--3--4--5--6--|

into its multiples:

func duplicate(event: Int) -> Int {
    return event * 2
}

--2--4--6--8--10--12--|

afterwards, filter them

func clip(event: Int) -> Int {
    return event < 10
}

--2--4--6--8--|

Then, think of these sequences as any kind of sequence, it can be a result of multiple HTTP responses from multiple requests that you chain together.

It can be a Void that usually results from a UIControl event. You can take a look at the documentation here:

ControlProperty / ControlEvent

However if you really need mutation, take a look at BehaviorRelay.

1
votes

The mistake you are making is in assuming that you must "initialize [an observable] with a value"; you don't do that. Instead you initialize an observable with a procedure that produces (zero or more) values.

Maybe concrete example will help...

let search = searchTextField.rx.text.orEmpty.asObservable()

The search variable above is of type Observable<String>. It "emits events over time" as the user is typing in the text field. Now with some suitable chaining on that observable, the code will be able to, for example, filter an array of user objects to only those who have the search text in their name.

You see, searchTextField.rx.text wasn't initialized with a value, it was initialized with a procedure that monitors the user's input into the text field.

Or another example:

let result = URLSession.shared.rx.data(request: URLRequest(url: URL(string: "http://myURL.com")!))

In the above, I'm initializing result with a procedure which, when subscribed to, will make a network request and emit the result.