gpt4 book ai didi

ios - UIButton 的 rx_tap 不通过嵌套订阅发送请求,如何直接转化为网络请求?

转载 作者:搜寻专家 更新时间:2023-11-01 07:28:51 24 4
gpt4 key购买 nike

假设我有一个 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)

看来上面两段逻辑不一样。后者订阅只在没有错误发生时才有效,就像普通订阅一样,而不是每次点击按钮时都订阅网络请求。

有什么办法可以把正式的片段扁平化吗?


添加了一段嵌套订阅:

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,订阅将被处理,我无法再次发送请求。

最佳答案

您有 2 种方法可以实现所请求的行为。第一个是用户map,然后是switchLatest,这是经典的方式。第二个是用户flatMap,如果你需要在网络请求序列中catch/retry

Ash Furrow 在 workshop demo code 中有一个很好的例子使用第二个示例和 Moya:

    submitButton.rx_tap.map { _ -> Observable<MoyaResponse> in
return provider.request(.Image)
}.flatMap() { obs in
return obs.filterSuccessfulStatusCodes()
.mapImage()
.catchError(self.presentError)
.filter({ (thing) -> Bool in
return thing != nil
})
}
.take(1)
.bindTo(imageView.rx_image)
.addDisposableTo(disposeBag)

或者,您可以检查 Github example in the RxSwift repository看看这些事情是如何处理的。

关于ios - UIButton 的 rx_tap 不通过嵌套订阅发送请求,如何直接转化为网络请求?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33968378/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com