DelegateProxy の Observable にイベントが飛んでこないケースがあった
RxSwift (RxCocoa) には、標準ライブラリの主要な delegate メッセージに対応する Observable が用意されています。DelegateProxy という仕組みです。
今回、その中で UISearchControllerDelegate
の各デリゲートメソッドを、RxSwift を用いて非同期的に扱いたかったのですが、ハマったのでまとめておきます。
うまくいかないパターン
class TheViewController: UIViewController, UISearchControllerDelegate {
var searchController = UISearchController()
let disposeBag = DisposeBag()
override func viewDidLoad() {
super.viewDidLoad()
searchController.delegate = self
// 1
searchController.rx.willPresent.subscribe(onNext: { _ in
/** これが呼ばれない **/
}).disposed(by: disposeBag)
}
// 2
func willPresentSearchController(_ searchController: UISearchController) {
/** こっちは呼ばれる ***/
}
}
上記の例では、UISearchControllerDelegate
を、TheViewController
自身にセットして、willPresentSearchController
を実装していますが、同時に RxSwift を使って willPresentSearchController
の Observable 変数である willPresent
に何らかの処理を非同期で行おうとしています。
こうすると、willPresent を subscribe しても実際にここにイベントが飛んでくることはありませんでした。
1 と 2 は同じタイミングで発火するものですが、delegate が viewController にセットされていることで 2 が優先されているといった状況になっているようです。
===
※ 実際には1つのクラス内でこんな妙な実装をすることはなく、プロトコルなどを使ってデリゲートの宣言や共通処理を切り出していたりするので、この問題のパターンになっていることに気付きませんでした。
うまくいくパターン
class TheViewController: UIViewController {
var searchController = UISearchController()
let disposeBag = DisposeBag()
override func viewDidLoad() {
super.viewDidLoad()
// 1
searchController.rx.willPresent.subscribe(onNext: { _ in
/** 呼ばれる **/
}).disposed(by: disposeBag)
}
}
上記サンプルを見れば当たり前なのですが...
RxSwift の DelegateProxy で与えられる Observable を購読して非同期で処理したい場合は、それに集約する必要があります。つまり UIViewControllerDelegate を ViewController に指定して、デリゲートメソッドを実装する方法を同時に行わないということです。
親にあたるクラスやプロトコルでデリゲートが実装されていると、末端のクラスでこのように RxSwift の DelegateProxy 経由の Observable が飛んでこないことがあります。
ソースコードが大規模になってくるとプロトコルや継承によって見通しが悪くなると起こりやすいので、気を付ける必要がありそうです。
Author And Source
この問題について(DelegateProxy の Observable にイベントが飛んでこないケースがあった), 我々は、より多くの情報をここで見つけました https://qiita.com/noramimiyuma/items/d3c0ffe5715fa75b3961著者帰属:元の著者の情報は、元の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 .