How to Observe Array Property Changes in Rxswift

How to observe array property changes in RxSwift

Most of the time, if you have control of the backing variable, you would prefer Variable to using rx_observe.

class ViewController: UIViewController {
var myArray : Variable<NSArray>!
}

The first time you'll use myArray, you would asign it like so

myArray = Variable(["a"])

Then, if you want to change its value

myArray.value = ["b"]

And you can easily observe its changes, using

myArray.asObservable().subscribeNext { value in
// ...
}

If you really want to use rx_observe (maybe because the variable is used elsewhere in your program and you don't want to change the API of your view controller), you would need to declare myArray as dynamic (another requirement is that the hosting class is a child of NSObject, here UIViewController satisfies this requirement). KVO is not implemented by default in swift, and using dynamic ensures access is done using the objective-c runtime, where KVO events are handled.

class ViewController: UIViewController {
dynamic var myArray: NSArray!
}

Documentation for this can be found here

How to subscribe on array changes using RxSwift?

In order to observe changes for your similarObjects , you have to make it of type Observable...

So for example you declare similarObjects as follow:

var similarObjects: PublishSubject<[Objects]> = PublishSubject<[Objects]>()

And you can subscribe to it by:

similarObjects
.asObservable()
.subscribe(onNext:{
print($0)
}

And when you want to assign it a value, you can use onNext operator

Example:

similarObjects.onNext(someArray)

By calling onNext, print($0) statement will be executed, make sure to subscribe before calling onNext to your Subject..

Observe changes in any property of any member of an array

You need to add the observer to all the Apple objects that you're adding in apples array.

First of all create a property named observers of type [NSKeyValueObservation] at class level, i.e.

var observers = [NSKeyValueObservation]()

Now, create a method that will append new Apple instances in apples array and add observer to it,

func addNewApple(_ apple: Apple) {
observers.append(apple.observe(\.color, options: [.new], changeHandler: { (apple, changes) in
if let newValue = changes.newValue {
print(newValue)
}
}))
apples.append(apple)
}

To observe a property of an object, that must be marked it @objc dynamic. So, the Apple definition goes like,

class Apple: NSObject {
@objc dynamic var color = "Red"
}

Now, you can use it as described below,

let myApple = Apple()
self.addNewApple(myApple)
myApple.color = "Blue"

Combining all the bits and pieces, the whole code can be written like,

class VC: UIViewController {    var apples = [Apple]()    var observers = [NSKeyValueObservation]()
override func viewDidLoad() { super.viewDidLoad() let myApple = Apple() self.addNewApple(myApple) myApple.color = "Blue" let otherApple = Apple() otherApple.color = "Green" } func addNewApple(_ apple: Apple) { observers.append(apple.observe(\.color, options: [.new], changeHandler: { (apple, changes) in if let newValue = changes.newValue { print(newValue) } })) apples.append(apple) }}

How to observe object's property in RxSwift?

Actually you should declare currentTemperature as Variable to observe the value changes. Your Forecast will become as this

class Forecast {

let city: City

var currentTemperature: Variable<String> = Variable("0")

init(city: City) {
self.city = city
}

func loadForecast() {
self.currentTemperature.value = "+10"
}

}

So now you can subscribe to listen the changes in currentTemperature as below,

class ForecastViewModel {

fileprivate let variableForecast: Variable<Forecast>

var navigationTitle: Observable<String> {
return Observable.just("No name")
}

init(forecast aForecast: Forecast) {
self.variableForecast = Variable(aForecast)

self.variableForecast.value.currentTemperature.asObservable().subscribe(onNext: { (value) in
print(value)
})

variableForecast.value.currentTemperature.value = "-15"
variableForecast.value.loadForecast()
}

}

RxSwift : Observe each element observable property in observable array

You can use Observable.combineLatest to combine all latest event in array's element's property

Here is the solution that worked for me.

class Player {
let stamina = Variable(0)
}

// ViewController
let disposeBag = DisposeBag()

// Array
let playerList: Variable<[Player]> = Variable([])

// Observing each player stamina at once
playerList.asObservable()
.flatMapLatest { players -> Observable<[Int]> in
let playerStaminaObservableList = players.map { $0.stamina.asObservable() }
return Observable.combineLatest { playerStaminaObservableList }
}
.subscribe(onNext: {
print("List of playerStamina: \($0)")
})
.disposed(by: disposeBag)

Feel free to correct any mistake.

In RxCocoa/RxSwift, how to observe BehaviorRelay[object] array size changed

From documentation:

  • parameter comparer: Equality comparer for computed key values.

I believe you should check the Equality with == operator. So, in your case, try this way:

BehaviorRelay<[object]>
.asObservable()
.distinctUntilChanged{ $0.count == $1.count}
.subscribe{....}


Related Topics



Leave a reply



Submit