2017-05-12 5 views
0

RxSwiftとMVVMを組み合わせて素晴らしいアーキテクチャを構築しようとしています。私はどのように正しくobservablesから来るエラーを処理するのだろうかと思います。RxSwiftとMVVMの処理エラー

私のViewModelには次のようになります関心事の明確な分離を、およびRESTエンドポイントを複数回呼び出す防ぐために観測可能な共有:

class MapViewModel { 

    private let disposeBag = DisposeBag() 

    private let listObservable: Observable<[MyObject]> 

    let list: Variable<[MyObject]> 
    let showError: Variable<Bool> 

    init() { 
     self.listObservable = getObservable().shareReplay(1) 

     self.list = Variable<[MyObject]>([]) 
     self.listObservable 
      .bind(to: list) 
      .addDisposableTo(self.disposeBag) 

     self.showError = Variable<Bool>(false) 
     self.listObservable 
      .subscribe(
       onError: { [weak self] error in 
        print("Error downloading: \(error)") 
        self?.showError.value = true 
      }).addDisposableTo(disposeBag) 
    } 
} 

私はそれはそれを行う方法を修正するためだと思いました。

しかし、私がこれを行うと、観測可能にエラーが送信されます。bind()呼び出しでエラーが処理されないため、RxSwiftからfatalErrorが返されます。この問題を解決するには

、私はにコードを変更:これは私にとってあまり明確思わ

self.listObservable 
    .subscribe(
     onNext: { [weak self] list in 
      self?.list.value = list 
     }, 
     onError: { [weak self] error in 
      print("Error downloading: \(error)") 
      self?.showError.value = true 
    }).addDisposableTo(disposeBag) 

。これで正しいアプローチは何でしょうか?

答えて

2

Variableを使用していると思います。可能な場合は避けてください。

このコードの私の印象:ビューモデルが作成されると

  • 、それはコールgetObservable()になります。

  • ユーザーからの入力はありません。

  • showError変数は、私がこのビューモデルは、より多くのように見えることを期待する代わりに、ブール

のボイドでなければなりませんので、トリガとしてではなく、に慣れることは、実際に値を渡しているようだ:

struct MapViewModel { 
    let list: Observable<[MyObject]> 
    let showError: Observable<Void> 

    init() { 
     let dataResult = getObservable() 
      .materialize() 
      .shareReplayLatestWhileConnected() 
     list = dataResult.map { $0.element } 
      .filter { $0 != nil } 
      .map { $0! } 
     showError = dataResult.map { $0.error } 
      .filter { $0 != nil } 
      .map { _ in } 
    } 
} 

上記で秘密のソースを使用すると、トリガーのためにそれを使用できるようにonNextイベントにエラーを変換するmaterializeの使用です。

サブスクリプション/バインドと廃棄バッグは、ビューモデルではなくビューコントローラ内にある必要があります。

+0

サンプルコードに誤りがありました。 'listObservable'を使用していたことを反映するように更新しました。答えをくれてありがとう、私は '変数'を 'Observable'に置き換えました。 – Jonas

+0

私は後世のために私の答えを更新しました。 @DanielT。 –

+0

可能なときに '変数'を避けるのはなぜですか?あなたの状態を増やすので? 'View Controller'の各' IBOutlet'プロパティに相当するかなりの 'outputs'を持つView Modelを持っています。これにより、オプションの 'observables'の束を避けることもできます。これは 'Variable'を使うのが適切な例ですか? –

関連する問題