Hi i’m just getting started with RxSwift and decided to make simple Currency Exchange application. My app has two view’s (allCurrenciesList and userFavouritesView). Basically all logic works, but only if i run networking func every single time one of view didAppear/didLoad. My point is two fetch it only once, and received many times, when necessary. Application fetch dictionary of currencies and in ViewModel pass it to BehaviorSubject, and when view being load/appear it just subscribe it, and use it in UITableView. Thanks
class ListViewModel {
let service: CurrencyService!
var curriencies = BehaviorRelay<[Currency]>(value: [])
var currienciesObservable: Observable<[Currency]> {
return curriencies.asObservable().share()
}
let disposeBag = DisposeBag()
init(service: CurrencyService) {
self.service = service
}
func fetchAllCurrencies() {
self.service.fetchAllSymbols { result in
switch result{
case .success(let currencies):
self.dictionaryIntoArray(currencies: currencies["symbols"] as! [String : Any])
case .failure:
print("error")
}
}
}
private func dictionaryIntoArray(currencies: [String: Any]) {
var currencyArray = [Currency]()
for (symbol, name) in currencies {
currencyArray.append(Currency(symbol: symbol, fullName: name as! String))
}
let sortedArray = currencyArray.sorted { $0.fullName < $1.fullName }
self.curriencies.accept(sortedArray)
}
allCurrenciesList
override func viewDidLoad() {
super.viewDidLoad()
setupView()
configureTableViewDataSource()
tableView.delegate = self
fetchData()
}
private func fetchData() {
viewModel.fetchAllCurrencies() // this func is necceserry everysingle time
viewModel.currienciesObservable.subscribe(onNext: { curriencies in
self.applySnapshot(curriencies: curriencies)
}).disposed(by: disposeBag)
}
userFavouritesView
override func viewDidLoad() {
super.viewDidLoad()
viewModel.fetchAllCurrencies() // this func is necceserry everysingle time
viewModel.currienciesObservable.subscribe(onNext: { allCurencies in
let selectedItems = UserDefaults.standard.array(forKey: "SelectedCells") as? [Int] ?? [Int]()
var currenciesArray: [Currency] = []
selectedItems.forEach { int in
self.pickerValues.append(allCurencies[int])
currenciesArray.append(allCurencies[int])
}
self.applySnapshot(curriencies: currenciesArray)
}).disposed(by: disposeBag)
}
2
Answers
The key here is to not use a Subject. They aren’t recommended for regular use. Just define the
currienciesObservable
directly.Something like this:
With the above, every time you subscribe to the
currenciesObservable
the fetch will be called.As I understand, it’s because your
fetchAllSymbols
function was not stored in the DisposeBag.