Observe array in Swift 3 using RxSwift

21,259

Solution 1

In Swift 3 using RxSwift 3.0 I will do that like this:

var array: Variable<[Int]> = Variable([1, 2, 3])
array.asObservable().subscribe(onNext: {
        updatedArray in
        print(updatedArray)
})
array.value.append(4) // it will trigger `onNext` event 

So the main difference is that you have to create an Variable object instead of using an explicit array.

Solution 2

The toObservable array-to-Observable constructor was deprecated.

Creating a cold observable

Use the from operator instead to create a cold observable:

let stream : Observable<Int> = Observable.from([1,2,3])

Or if you need the whole array as an entry, use the just operator to create a cold observable.

let singleEmissionStream : Observable<[Int]> = Observable.just([1,2,3])

Elements of the array at the time that the from or just operator is called will be final set of emissions on the onNext events and will end with an onCompleted event. Changes to the array will not be recognized as new events for this observable sequence.

This means that if you don't need to listen to changes on that array, you can use the just and the from operator to create the observable.

But what if I need to listen to changes on the array elements?

To observe changes on an array [E], you need to use a hot observable like the Variable RxSwift unit, as specified in the answer by k8mil. You will have an instance of type Variable<[E]> wherein each onNext emission is the current state of the array.

What is the difference between a cold and a hot observable?

A distinction between cold and hot observables are explained in the documentation of RxSwift and in reactivex.io. Below is a short description of cold observables in comparison to hot observables.

Cold observables start running upon subscription, i.e., the observable sequence only starts pushing values to the observers when Subscribe is called. [...] This is different from hot observables such as mouse move events or stock tickers which are already producing values even before a subscription is active.

The from and the just operators take the current state of the array when the code runs, thus finalizing the set of emissions it will fire for its observable sequence, no matter when it is subscribed to. That is why changes to the set of elements in the array at a later time will not change the set of elements recognized as the emissions during the creation of the observable using the from or just operators.

Share:
21,259
pableiros
Author by

pableiros

iOS Developer all day long, sometimes Android Developer and no often Web Developer...

Updated on July 01, 2020

Comments

  • pableiros
    pableiros almost 4 years

    To create an observable array using RxSwift in Swift 2, I use to do this:

    [1, 2, 3].toObservable().subscribeNext { print($0) }
    

    But in Swift 3, it doesn't work anymore, I got this error:

    Value of type '[Int]' has no member 'toObservable'

    How can I create an RxSwift observable array from a swift array?

  • kamwysoc
    kamwysoc almost 7 years
    Are you sure about that stream you create will work correctly? I've tested it and changes on the array not trigger any event. Could you provide some code with subscription? Thanks You can look at my code: pastebin.com/phbNjmec
  • dsapalo
    dsapalo almost 7 years
    Hi, I must have misread the question. I thought that the question was how to arrive at an Observable<E> from a Swift array of type [E]. It did not specify whether it was a hot observable or a cold observable. I'll note that the approach I proposed is a cold observable, and explain its difference with your hot observable implementation which uses a Variable.
  • Shabarinath Pabba
    Shabarinath Pabba about 6 years
    What do you do if you want to copy the values inside updatedArray to another Array in the same file?