をCombineでもやりたいよねって話。
ただし、Combineの場合 Swift Foundation の Set が使われており DisposeBag.insert(_:) に相当するfuncが存在しないので自前で用意する必要があります。
Set は struct なので mutating を付けるのがミソ。
public extension Set where Element == AnyCancellable {
mutating func insert(_ cancellables: [AnyCancellable]) {
cancellables.forEach {
$0.store(in: &self)
}
}
mutating func insert(_ cancellables: AnyCancellable...) {
insert(cancellables)
}
}
これで
hoge.sink { ~ }
.store(in: &cancellables)
fuga.sink { ~ }
.store(in: &cancellables)
が
cancellables.insert(
hoge.sink { ~ },
fuga.sink { ~ }
)
と書けるようになりました🎉
折角なのでresultBuilderも作っちゃいましょう。
public extension Set where Element == AnyCancellable {
/// Convenience function allows a list of cancellables to be gathered for cancel.
mutating func insert(@AnyCancellableBuilder _ builder: () -> [AnyCancellable]) {
insert(builder())
}
@resultBuilder
struct AnyCancellableBuilder {
static func buildBlock(_ cancellables: AnyCancellable...) -> [AnyCancellable] {
cancellables
}
}
}
これでRxSwift時代と同じように書けるぞい💪('ω'💪)
cancellables.insert {
hoge.sink { ~ }
fuga.sink { ~ }
}