Greg
Greg

Reputation: 25459

RxSwift network status observable

I have a method 'getProducts' in my view model:

struct MyViewModel {
    func getProducts(categoryId: Int) -> Observable<[Product]> {
        return api.products(categoryId: categoryId)
    }
    var isRunning: Observable <Bool> = {
        ...
    }
}

api.products is a private variable which uses URLSession rx extension: session.rx.data(...) in the background.

I would like to have some isRunning observer in my view model which I could subscribe to to know if it's do a network request.

Is it something I could do without making any amendments to my api class?

I'm new in reactive programming so any help would be appreciated.

Thanks.

Upvotes: 2

Views: 2261

Answers (1)

Nimble
Nimble

Reputation: 1017

Here's a solution using a helper class written by RxSwift authors in RxSwift Examples called ActivityIndicator.

The ideas is simple

struct MyViewModel {
    /// 1. Create an instance of ActivityIndicator in your viewModel. You can make it private
    private let activityIndicator = ActivityIndicator()

    /// 2. Make public access to observable part of ActivityIndicator as you already mentioned in your question
    var isRunning: Observable<Bool> {
        return activityIndicator.asObservable()
    }

    func getProducts(categoryId: Int) -> Observable<[Product]> {
        return api.products(categoryId: categoryId)
            .trackActivity(activityIndicator) /// 3. Call trackActivity method in your observable network call
    }
}

In related ViewController you can now subscribe to isRunning property. For instance:

    viewModel.isLoading.subscribe(onNext: { loading in
        print(loading)
    }).disposed(by: bag)

Upvotes: 3

Related Questions