【问题标题】:RxSwift - Receive the same event at two ViewControllers at the same timeRxSwift - 同时在两个 ViewControllers 接收相同的事件
【发布时间】:2022-09-29 01:08:48
【问题描述】:

嗨,我刚刚开始使用 RxSwift,并决定制作简单的货币兑换应用程序。我的应用程序有两个视图(allCurrenciesList 和 userFavouritesView)。基本上所有逻辑都有效,但前提是我每次都运行网络功能,其中一个是查看 didAppear/didLoad。我的观点是两次只取一次,并在必要时收到多次。应用程序获取货币字典并在 ViewModel 中将其传递给 BehaviorSubject,当视图加载/出现时,只需订阅它,并在 UITableView 中使用它。谢谢

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)
    } 

所有货币列表

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)
    }

用户收藏查看

 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)
        
    }

    标签: ios swift rx-swift


    【解决方案1】:

    这里的关键是不使用主题。不建议经常使用它们。只需直接定义currienciesObservable

    像这样的东西:

    class ListViewModel {
        let currienciesObservable: Observable<[Currency]>
    
        init(service: CurrencyService) {
            self.currienciesObservable = service.rx_fetchAllSymbols()
                .map { currencies in
                    currencies["symbols"]?.map { Currency(symbol: $0.key, fullName: $0.value as! String) }
                        .sorted(by: { $0.fullName < $1.fullName }) ?? []
                }
        }
    }
    
    extension CurrencyService {
        func rx_fetchAllSymbols() -> Observable<[String: [String: Any]]> {
            Observable.create { observer in
                self.fetchAllSymbols { result in
                    switch result {
                    case let .success(currencies):
                        observer.onNext(currencies)
                        observer.onCompleted()
                    case let .failure(error):
                        observer.onError(error)
                    }
                }
                return Disposables.create()
            }
        }
    }
    

    有了以上内容,每次订阅currenciesObservable 时,都会调用 fetch。

    【讨论】:

      【解决方案2】:

      据我了解,这是因为您的 fetchAllSymbols 函数未存储在 DisposeBag 中。

      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")
                      
               }
          }.dispose(by: disposeBag)
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-01-14
        • 1970-01-01
        • 1970-01-01
        • 2012-07-14
        • 2021-04-23
        • 1970-01-01
        • 2010-10-30
        • 2016-05-08
        相关资源
        最近更新 更多