Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Display activity indicator with RxSwift and MVVM

I have a layered architectured application where I am getting array of objects in ViewModel and binding it with tableview in ViewController. Following is my code: ViewModel:

func getManufacturerList() -> Single<[ManufacturerItem]> {
    return self.fetchManufacturerInteractor.getManufacturerList()
        .map { $0.map { ManufacturerItem(
            manufacturerName: $0.manufacturerName,
            manufacturerID: $0.manufacturerID) } }
}

Above function receives array of objects from some other layer which again gets it from NetworkLayer.
ViewController:

private func setUpViewBinding() {
    manufacturerViewModel.getManufacturerList()
        .asObservable()
        .bind(to: tableView.rx.items(cellIdentifier: LanguageSelectionTableViewCell.Identifier,
                                     cellType: LanguageSelectionTableViewCell.self)) { row, manufacturer, cell in
            cell.textLabel?.text = manufacturer.manufacturerName
            cell.textLabel?.font = AppFonts.appBoldFont(size: 16).value
            cell.accessibilityIdentifier = "rowLanguage\(row+1)"
            cell.textLabel?.accessibilityIdentifier = tblCellLabelAccessibilityIdentifier
    }.disposed(by: self.disposeBag)
}

Now where should I add the code for showing/hiding the activity indicator?

like image 578
pankaj Avatar asked Jan 27 '23 21:01

pankaj


1 Answers

ViewModel should handles showing or hiding IndicatorView (if there is a single loading view) because your view needs to be dumb, use BehaviorRelay instead of variable (variable is depricated)

in viewModel

// create a subject and set the starter state, every time your viewModel 
// needs to show or hide a loading, just send an event
let showLoading = BehaviorRelay<Bool>(value: true)

// your async function
func getManufacturerList() -> Observable {
  // notify subscriber to show the indicator view
  showLoading.accept(true)

  // do some works


  // notify subscribers to hide the indicator view
  showLoading.accept(false)
}

and in your view controller

// bind your indicator view to that subject and wait for events
showLoading.asObservable().observeOn(MainScheduler.instance).bind(to: indicatorView.rx.isHidden).disposed(by: disposeBag)
like image 192
Farshad jahanmanesh Avatar answered Jan 29 '23 11:01

Farshad jahanmanesh