web-dev-qa-db-ja.com

RxSwiftが異なる種類のオブザーバブルをマージする

RxSwiftで2種類のObservablesをマージするにはどうすればよいですか?

例えば:

_var a: Observable<Int>
var b: Observable<Void>
_

Observable.of(a,b).merge()は、型パラメーターの違いにより不可能です。

14
Swift Hipster

それらをmergeするには、Elementと同じタイプである必要があります。

したがって、1つのオプションは、型情報を破棄してAnyObjectにキャストすることです。今、それらをマージすることができます:

let stringSubject = PublishSubject<String>()
let stringObservable = stringSubject.asObservable().map { $0 as AnyObject }

let intSubject = PublishSubject<Int>()
let intObservable = intSubject.asObservable().map { $0 as AnyObject }

Observable.of(stringObservable, intObservable).merge()
    .subscribeNext { print($0) }
    .addDisposableTo(disposeBag)

stringSubject.onNext("a")
stringSubject.onNext("b")
intSubject.onNext(1)
intSubject.onNext(2)
stringSubject.onNext("c")

出力:

a
b
1
2
c

別のオプションは、次に列挙型でラップすることです:

enum Container {
    case S(String)
    case I(Int)
}

let stringSubject = PublishSubject<String>()
let stringObservable = stringSubject.asObservable().map { Container.S($0) }

let intSubject = PublishSubject<Int>()
let intObservable = intSubject.asObservable().map { Container.I($0) }

Observable.of(stringObservable, intObservable).merge()
    .subscribeNext { e in
        switch e {
        case .S(let str):
            print("next element is a STRING: \(str)")
        case .I(let int):
            print("next element is an INT: \(int)")
        }
    }
    .addDisposableTo(disposeBag)

stringSubject.onNext("a")
stringSubject.onNext("b")
intSubject.onNext(1)
intSubject.onNext(2)
stringSubject.onNext("c")

出力:

次の要素はSTRINGです:a
次の要素は文字列です:b
次の要素はINTです:1
次の要素はINT:2
次の要素は文字列です:c

さまざまな型のObservablesを組み合わせることができる他の演算子(ZipcombineLatestなど)については、mergeのように機能する演算子はありません。しかし、それらをチェックしてください。要件に適している場合があります。

27
solidcell

2つのオブザーバブルをマージしたいがElementの値は必要なく、Expression of type 'AnyObject' is unusedオプションを使用するときに.map { $0 as AnyObject }を取り除く方法が必要な場合:

var a = PublishSubject<Int>()
var b = PublishSubject<Void>()

let observable = Observable.merge(a.map { _ in return Void() }, b)
1
iOSDev