tiguero tiguero - 1 year ago 88
Swift Question

How to configure a Bool Stream in RxSwift

I am willing to force a reload of a

when new content is fetched from a web-service while using
. I can't figure out why I don't receive an event on newContent with the following code when my onComplete closure is properly called.

class ListingView : UIView {

var newContentStream: Observable<Bool>?
let disposeBag = DisposeBag()

@IBOutlet weak var collectionView: UICollectionView!

weak var viewModel: ListingViewModel?

func bind(viewModel: ListingViewModel) {
self.viewModel = viewModel

func configure() {
guard let viewModel = self.viewModel else { return }

self.newContentStream = viewModel.newContent.asObservable()
self.newContentStream!.subscribeNext { _ in

and then within my viewModel:

class ListingViewModel {
let dataSource = ListingViewDataSoure()
var newContent = Variable(false)

func mount() {
let onComplete : ([item]? -> Void) = { [weak self] items in
self?.dataSource.items = items
self?.newContent = Variable(true)

guard let URL = API.generateURL() else { return }
Requestor.fetchAll(onComplete, fromURL: URL)

Answer Source

It's because self?.newContent = Variable(true) is replacing the newContent with an entirely new Variable, after you've already subscribed to the original here:

self.newContentStream = viewModel.newContent.asObservable()
self.newContentStream!.subscribeNext { ......

That subscription in your UIView is now listening to an Observable that no one is ever going to be sending a Next event on.

Instead, you should be sending out a Next event on the current (and only) newContent Variable/Observable:

self?.newContent.value = true

You could fix it and continue to use a newContent Variable and a reloadData call, however, I wouldn't recommend doing it like this. Instead, check out RxDataSources.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download