2017-08-02 20 views
1

ネットワークからさまざまなタイプのモデルを要求し、それらを1つのモデルに結合する必要があります。 複数のオブザーバブルを連鎖させ、別のオブザーバブルを返すことはどのように可能ですか?RxSwiftを異なるタイプで観測可能

私のようなものがあります:

func fetchDevices() -> Observable<DataResponse<[DeviceModel]>> 

func fetchRooms() -> Observable<DataResponse<[RoomModel]>> 

func fetchSections() -> Observable<DataResponse<[SectionModel]>> 

をし、私のような何か実行する必要があります。RxSwiftでそれを達成するためにどのように

func fetchAll() -> Observable<(AllModels, Error)> { 
    fetchSections() 

    // Then if sections is ok I need to fetch rooms 
    fetchRooms() 

    // Then - fetch devices 
    fetchDevices() 

    // And if everything is ok create AllModels class and return it 
    // Or return error if any request fails 
    return AllModels(sections: sections, rooms: rooms, devices:devices) 
    } 

を?私はドキュメントや例を読んでいますが、同じタイプのオブザーバブルをどのようにチェーン化するかを理解しています

+0

私はZIPがあなたが探しているものだと思います:http://reactivex.io/documentation/operators/zip.html – ULazdins

答えて

4

try combineLatestオペレータ。あなたは、複数の観測を組み合わせることができます。

let data = Observable.combineLatest(fetchDevices, fetchRooms, fetchSections) 
    { devices, rooms, sections in 
     return AllModels(sections: sections, rooms: rooms, devices:devices) 
    } 
    .distinctUntilChanged() 
    .shareReplay(1) 

そして、あなたはそれを購読する:

data.subscribe(onNext: {models in 
    // do something with your AllModels object 
}) 
.disposed(by: bag) 
0

私はフェッチモデルはViewModelにに常駐すべき方法を考えて、そしてイベントがそれらを呼び出す開始を待っているべきですまったく、または彼らは実行を開始しません。

ボタンが3つのメソッドを呼び出し、関数呼び出しが成功した場合に有効になるもう1つのボタンがあるとします。

ViewController内にViewModelがあるとします。 ViewModelには

let viewModel = ViewModel() 

struct Input { 
    buttonTap: Driver<Void> 
} 
struct Output { 
    canProcessNext: Driver<Bool> 
} 

は、その後、あなたが明確にViewModelににこのように機能させることにより、出力にあなたの入力を変換することができ、このようなあなたの抽象化されたI/Oイベントを宣言します。 viewDidLoadで

func transform(input: Input) -> Output { 
    // TODO: transform your button tap event into fetch result. 

} 

let output = viewModel.transform(input: yourButton.rx.tap.asDriver()) 
output.drive(nextButton.rx.isEnabled).disposed(by: disposeBag) 

今、すべての準備ができていますが、あなたの三つの方法を組み合わせることだ - のViewModelに入れ。

func fetchDevices() -> Observable<DataResponse<[DeviceModel]>> 
func fetchRooms() -> Observable<DataResponse<[RoomModel]>> 
func fetchSections() -> Observable<DataResponse<[SectionModel]>> 

私はちょうどそれを動作させるについて書いて、また、あなたのアプリケーションのための全体の設計を考慮していないだけのは、「TODO」

let result = input.buttonTap.withLatestFrom(
    Observable.combineLatest(fetchDevices(), fetchRooms(), fetchSections()) { devices, rooms, sections in 
    // do your job with response data and refine final result to continue 
    return result 
}.asDriver(onErrorJustReturn: true)) 

return Output(canProcessNext: result) 

を終了してみましょう。 ViewControllerの中にすべてを置くことは、特にRxデザインを使用して行く方法ではありません。将来のメンテナンスのためにVC & ViewModelのログインを分けることは良い選択だと思います。 this sampleを探してください、それはあなたを助けるかもしれないと思います。

関連する問題