UIButton があるとしますloginButton
。次のコードでボタンをタップしながらネットワーク リクエストを送信します。
override func viewDidLoad() {
super.viewDidLoad()
let session = self.session // NSURLSession
loginButton.rx_tap.subscribeNext { [unowned self] in
session.rx_response(myRequest).subscribe { event in
switch event {
case .Next(let data, let response):
// Handling Response
case .Error(let error):
// Handling Error
default:
return
}
}.addDisposableTo(disposeBag)
}.addDisposableTo(disposeBag)
}
その場合、ネットワークリクエストでエラーが発生しても、ボタンをタップすることでリクエストを再送信できます。
コードは非常にうまく機能しますが、ネストされたサブスクリプションのために少し見にくいと思いました。flatMap
サブスクリプションを平坦化する方法を試しました:
loginButton.rx_tap
.flatMap {
return session.rx_response(myRequest)
}
.subscribe { event in
switch event {
case .Next(let data, let response):
print("Next")
case .Error(let error):
print(error)
default:
return
}
}
.addDisposableTo(disposeBag)
上記の 2 つのスニペットは異なるロジックのようです。後者のサブスクリプションは、ボタンがタップされるたびにネットワーク リクエストをサブスクライブするのではなく、通常のサブスクリプションと同じようにエラーが発生していない間のみ機能します。
正式なスニペットを平坦化する方法はありますか?
ネストされたサブスクリプションのスニペットを追加しました:
loginButton.rx_tap
.debug("LoginButtonTapped")
.subscribeNext {
let disposable = session.rx_response(myRequest)
.debug("AuthorizationRequest")
.subscribe(
onNext: { [unowned self] data, response in
// Handling Response
},
onError: { [unowned self] error in
// Showing Error
})
disposable.addDisposableTo(self.disposeBag)
let alert = UIAlertController(title: "Please Wait.", message: "Requesting Tokens", preferredStyle: .Alert)
alert.addAction(UIAlertAction(title: "Cancel", style: .Cancel) { _ in
disposable.dispose()
alert.dismissViewControllerAnimated(true, completion: nil)
})
self.presentViewController(alert, animated: true, completion: nil)
}.addDisposableTo(disposeBag)
エラーは、次のコードを使用してキャッチできます。
let disposable = loginButton.rx_tap
.map { session.rx_response(request) }
.flatMap { [unowned self] in $0.catchError(self.presentError) }
.subscribeNext { data, response in
// Handling Response
}
必要に応じて、ネットワーク リクエストもキャンセルする必要があります。上記のスニペットで手動で破棄するdisposable
と、サブスクリプションが破棄され、リクエストを再度送信できなくなります。