ios - rx.tap 订阅已完成的按钮

标签 ios swift reactive-programming rx-swift

我是 RxSwift 的新手,我正在尝试实现登录 facebook 功能,这就是我正在做的事情:

loginButton.rx.tap
            .debug("login tapped")
            .flatMap { [weak self] ()->Observable<AccessToken> in
                guard let strongSelf = self else {
                    throw NetworkError.requestCancelled
                }
                return strongSelf.viewModel.loginFacebook(from: strongSelf)
            }
            .flatMap { [weak self] accessToken->Observable<(accessToken: String, userId: String)> in
                guard let strongSelf = self else {
                    throw NetworkError.requestCancelled
                }
                return strongSelf.viewModel.requestUserInfo(token: accessToken)
            }
            .flatMap { [weak self] (accessToken: String, userId: String)->Observable<LoginResult> in
                guard let strongSelf = self else {
                    throw NetworkError.requestCancelled
                }
                return strongSelf.viewModel.authenticate(accessToken: accessToken, userId: userId)
            }
            .catchError({ error -> Observable<LoginResult> in
                return Observable.just(LoginResult.failure(error: error as! NetworkError))
            })
            .subscribe (onNext:{ [weak self] result in
                guard let strongSelf = self else {
                    return
                }

                switch result {
                case .success:
                    // do something with success
                    }
                case .failure(let error):
                    // do something with error
                }
            }, onCompleted: {
                print("rx.tap completed")
            })
            .disposed(by: disposeBag)

问题是,当我点击登录按钮,然后关闭弹出的 Facebook 登录窗口时,我对 rx.tap 的订阅达到 onCompleted,所以当我尝试时再次点击按钮,什么也没有发生。我该如何处理这个案子?任何建议都会有所帮助。

最佳答案

这是您的链的简化方案:

loginButton.rx.tap
    .flatMap({ (_) -> Observable<Void> in
        throw NSError(domain: "", code: 0, userInfo: [:])
    })
    .catchError({ error -> Observable<Void> in
        return Observable<Void>.just()
    })
    .subscribe()

当您生成Observable<Void>.just()时在catchError block 或其他 block 中的类似内容,它只会触发一次,这就是为什么您收到 completed之后就没有其他事情发生了。我建议将您拥有的所有代码放入 flatMapLatest例如。结果代码将是:

loginButton.rx.tap
    .flatMapLatest({ _ -> Observable<Void> in
        return Observable<Void>
            .just()
            .flatMap({ (_) -> Observable<Void> in
                throw NSError(domain: "", code: 0, userInfo: [:])
            })
            .catchError({ error -> Observable<Void> in
                return Observable<Void>.just()
            })
    })
    .subscribe()

希望对你有帮助

附注检查similar answer来自 RxSwift 开发团队成员

关于ios - rx.tap 订阅已完成的按钮,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44468811/

相关文章:

ios - Swift 中没有像 Sqlite 这样的模块

应用程序购买中的 IO - 沙盒的报告/交易日志

swift - 在 Swift 中使用 Soap Engine 进行数据解析

ios - Collection View 自动调整大小并设置重复背景

iphone - 基于 NSStrings 数组从对象的 NSArray 中提取字符串

iphone - iOS - Amazon S3 下载缓慢

ios - 使用 Facebook v4 登录 ParseUI 时没有访问 token ( session )

使用 Lamina : Simple clock code? 的 Clojure 函数式响应式(Reactive)编程 (FRP)

java - Webflux订阅者

java - Hystrix 执行模式