RxSwift:点按一个按钮即可向Alamofire发出请求,如何使其有效?

时间:2019-11-13 09:48:06

标签: ios swift rx-swift

我有一些UI rx按钮点击,我想将其连接到网络rx部分。

这是Rx btn龙头部分:

btn.rx.tap.take(1).flatMap {  [unowned self]  () -> Observable<Bool>  in
            // ...
            return NetManager.standard.request()
        }.debug().do(onNext: { _ in
                print("The data flows here")
            }).flatMapLatest { (echo: Bool) -> Observable<Bool> in
            if echo{
                if let app = UIApplication.shared.delegate as? AppDelegate{
                    app.goHome()
                }
                return Observable.of(true)
            }
            else{
                return Observable.of(false)
            }
        }.subscribe(onNext: { (result) in
            // ... , do sth with result
        }).disposed(by: rx.disposeBag)

以下是Alamofire的净要求部分:

class NetManager: NSObject {

    static let standard = NetManager()
    var dataRequest: DataRequest?

    func request() -> Observable<Bool> {
           return Observable<Bool>.create{ (observer) -> Disposable in
                    let data = // ...
                    // ...
                    self.dataRequest = AF.request(aURL, method: HTTPMethod.post, parameters: data, encoder: JSONParameterEncoder.prettyPrinted, headers: aHead).response { (response: DataResponse<Data?>) in
                            self.hud?.hide()
                           if let data = response.data{
                               observer.onNext(true)
                                // ....
                           }
                           else{
                               observer.onNext(false)
                           }
                       }
                    observer.onCompleted()
                    return Disposables.create{}
           }
       }

}

这是调试信息:

  

Controller.swift:141(viewDidLoad())->已订阅

     

Controller.swift:141(viewDidLoad())->事件已完成

     

Controller.swift:141(viewDidLoad())-> isDisposed

结果是,do( next )部分似乎尚未被调用。因为控制台中没有print


问题是,如何使rx逻辑起作用?


这是我尝试过的:

btn.rx.tap.flatMap转到btn.rx.tap.take(1).flatMap

因为来自this issue

  

如果flatMap完成将终止外部流,则意味着流中将不再注册按钮轻按,这真的没有道理。


来自this question

  btn.rx.tap.map { () -> Observable<Bool> in

    return NetManager.standard.request()
  }.flatMapLatest { (observer: Observable<Bool>) -> Observable<Bool> in

    // of cource, I can subscribe to observer
    /*
     observer.subscribe(onNext: { (echo) in

     })
     */


    // how to get the event element elegantly.

    return Observable.of(false)
}.subscribe(onNext: { (_) in

}).disposed(by: rx.disposeBag)

如何更优雅地做到这一点。

1 个答案:

答案 0 :(得分:2)

这里的主要问题是,在执行网络请求时,您没有等待网络呼叫做出响应。因此observer.onComplete()observer.onNext()

之前被触发
class NetManager: NSObject {

static let standard = NetManager()
var dataRequest: DataRequest?

func request() -> Observable<Bool> {
       return Observable<Bool>.create { (observer) -> Disposable in
                let data = // ...
                // ...
                self.dataRequest = AF.request(aURL, method: HTTPMethod.post, parameters: data, encoder: JSONParameterEncoder.prettyPrinted, headers: aHead).response { (response: DataResponse<Data?>) in
                        self.hud?.hide()
                       if let data = response.data {
                           observer.onNext(true)
                           // ... 
                       }
                       else {
                           observer.onNext(false)
                       }
                       observer.onComplete() // Moving it here instead will wait for the response
                }
                return Disposables.create { }
       }
   }
}

在这一点上,您的代码应该可以按原样工作,但是您仍然使一个非常简单的事情变得过于复杂。

这是做什么:

btn.rx.tap
    .flatMap { _ in
        return NetManager.standard.request()
    }
    .subscribe(onNext: { (success) in
        if success {
            if let app = UIApplication.shared.delegate as? AppDelegate {
                app.goHome()
            }
        } 
    })
    .disposed(by: rx.disposeBag)