PublishSubjectを使いこなす
はじめに
RxSwiftを勉強し始めてまだ日が浅いですが、値を返す際にPublishSubjectを使うと便利です。
asObservableでObserbableにできるし、呼び出し先でsubscribeもできます。
PublishSubjectを使ってシンプルなアプリケーションを作成してみました。
PublishSubjectミニマムアプリ
今回作成したアプリは画面の文字が変わるだけのアプリです。
初めはstartという文字で3秒経過するとendという文字に変更させます。
ラベルの文字を変更するロジッククラス
start()とend()の中でstateSubject.onNext()を呼んでいますが、ここで状態が変わると、subscribeしているところにストリーム(処理)が流れます。
今回はViewController側でsubscribeします。
enum State {
case start
case end
}
class Logic {
//PublishSubjectのメンバを作成しています、
private let stateSubject = PublishSubject<State>()
//SubscribeさせるためにObservableとして外に公開する
var stateChanged: Observable<State> {
return stateSubject.share().asObservable()
}
func start() {
stateSubject.onNext(.start)
}
func end() {
stateSubject.onNext(.end)
}
}
Subscribeして受け取る
起動するとlogic.start() が呼ばれ、3秒後にlogic.end()が呼ばれてラベルの文字が変わります。
class ViewController: UIViewController {
@IBOutlet weak var label: UILabel!
var logic = Logic()
let disposeBag = DisposeBag()
override func viewDidLoad() {
super.viewDidLoad()
//PublishSubjectに変更があったらここに来る
logic.stateChanged.observeOn(MainScheduler.instance).subscribe(onNext: {[weak self] state in
self?.changeLabelText(state: state)
}).disposed(by: disposeBag)
//上の処理が呼ばれる
logic.start()
DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
//上の処理が呼ばれる
self.logic.end()
}
}
func changeLabelText(state: State){
switch state {
case .start:
label.text = "start"
case .end:
label.text = "end"
}
}
}