🌾
[Swift] [Combine] Publisher を flatMap() 内に隠蔽して直接 subscribe するのを避ける方法
はじめに
以下の記事にもあるように、『Failure となる可能性がある Publisher を直接 subscribe している場合、一度でも Failure が発生すると、その時点で Completion となり、Output を受け付けなくなる』という挙動を示します。
その回避方法として、記事内では flatMap() 内での tryMap() -> catch -> Empty の合わせ技
を紹介しているのですが、そもそも外側にある Publisher を flatMap()
内に隠蔽する方法について、いくつかパターンがあるので、それを紹介する記事になります。
以下は共通のコードになります。
前提
import Combine
import Foundation
var cancellables: Set<AnyCancellable> = []
let numPublisher = PassthroughSubject<Int, Never>()
Just()
を使う ← オススメ
方法1: 以下になります。
numPublisher
.flatMap {
Just($0)
.eraseToAnyPublisher()
}
.sink { print("\($0)") }
.store(in: &cancellables)
言われてみれば、それはそうなのですが、Just()
を使えば一発ですね。
これが一番シンプルだと思います。
map()
による配列変換 -> Array.publisher
を使う
方法2: 以下になります。
numPublisher
.map { [$0] }
.flatMap {
$0.publisher
}
.sink { print("\($0)") }
.store(in: &cancellables)
配列であれば、.publisher
によるアクセスで、Publisher 変換できるので、それを利用した形になります。
collect(1)
による配列変換 -> Array.publisher
を使う
方法3: 以下になります。
numPublisher
.collect(1)
.flatMap {
$0.publisher
}
.sink { print("\($0)") }
.store(in: &cancellables)
方法2
とやっていることは同じです。
ちょっと玄人感があります。
結論
- Publisher を
flatMap()
内に隠蔽して直接 subscribe するのを避けるなら、Just()
を使おう
以上になります。
Discussion