CombineによるPublisherの受け渡し
はじめに
RxSwift
を利用したVIPER
アーキテクチャのソースコードをcombine
で書き直している。
RxSwift
では、Interactor
がAPIから非同期処理で取得したデータをPresenter
に渡す際、Single
オブジェクトとして扱っていた。Single
だったところをcombine
ではFuture
オブジェクトにしたのだが、両者はGenerics
の型の数が異なる。直接参考になるソースを見つけられなかったため我流のものだが書き残しておく。ただ、もっと良い方法があると思われるので、詳しい方にご教示いただきたいというのが正直なところである。
ソースコード
fetchFutureOnPresenter(flag: Bool)
にtrue
を入れればString
がInt
に変換された値が返ってくる。false
にすればPresenter
を経由せずにエラーが投げられることをplaygroundで動作確認をした。
struct APIError: Error {
var description: String
}
// InteractorがAPIにアクセスしてレスポンスを取得する想定
func fetchFutureOnInteractor(flag: Bool) -> AnyPublisher<String, Error> {
return Future<String, Error>{ promise in
///
/// 実際はここに非同期処理を書く想定
///
// 非同期処理の結果によって、場合分け
if flag {
promise(.success("0"))
} else {
promise(.failure(APIError(description: "☓")))
}
}
.eraseToAnyPublisher()
}
// PresenterがInteractorのメソッドから取得したデータをViewに渡す用に変換する想定
// flatMapでAnyPublisher<String, Error>からAnyPublisher<Int, Error>に変換
func fetchFutureOnPresenter(flag: Bool) -> AnyPublisher<Int, Error> {
return fetchFutureOnInteractor(flag: flag)
.flatMap { output -> AnyPublisher<Int, Error> in // クロージャの戻り値をIntにする
Future<Int, Error>{ promise in
promise(.success(Int(output)!)) // Intにキャスト、エラー(Failure)は、ここでは記載しない
}
.eraseToAnyPublisher()
}
.eraseToAnyPublisher()
}
// Presenterが購読(.sink)
let cancellable = fetchFutureOnPresenter(flag: /* true or false */)
.sink(receiveCompletion: { completion in
switch completion {
case .finished:
break
case .failure(let error):
// Interactorの.failureはここに投げられる
print("error \(error)")
}
}, receiveValue: { value in
// このvalueを元にViewが参照する値を更新する想定
print("value \(value)")
})
Author And Source
この問題について(CombineによるPublisherの受け渡し), 我々は、より多くの情報をここで見つけました https://qiita.com/moccow/items/ab153b17eead00873d68著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .