2017-05-12 31 views
0

我試圖把一個很好的架構,RxSwift和MVVM。我想知道如何正確處理來自observables的錯誤。處理錯誤與RxSwift和MVVM

我的視圖模型看起來像:

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

我認爲這是糾正辦法做到這一點:關注完全分離,並共享觀測的,以防止調用REST端點多次。

但是,當我這樣做 - 和observable發送錯誤 - 我從RxSwift得到一個fatalError,因爲錯誤不在bind()調用中處理。

爲了解決這個問題,我改變了代碼:

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 s的扔你了,我認爲。儘可能避免使用它們。

我這段代碼的印象:

  • 在創建視圖模型,它使一個電話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 } 
    } 
} 

在上面的祕訣是利用materialize到錯誤轉換爲onNext事件,所以你可以用它來觸發。

的訂閱/結合和處置袋應該在視圖控制器,而不是在視圖模型。

+0

我的示例代碼出現錯誤。我更新了它,以反映我使用'listObservable'是兩種情況。感謝您的回答,我用'Observable'替換了'Variable's。 – Jonas

+0

爲了後代的緣故,我更新了答案。 –

+0

@DanielT。爲什麼在可能的情況下避免變量?因爲你添加更多的狀態?我有一個視圖模型,其中有很多'outputs'對應於'View Controller'中的每個'IBOutlet'屬性。這也讓我避免了一堆可選的'observables'。這是一個適合使用'Variable's的實例嗎? –