RxSwift:连接到可连接的Observable多次

时间:2017-07-10 13:31:33

标签: ios swift rx-swift

我在iOS应用程序中采用MVVM模式。我在视图模型中公开了一系列Observable作为公共属性,并将UI绑定到这些属性。这些Observable是从一个私有的可连接的observable创建的。

视图控制器类然后调用“execute”方法来触发网络请求。但是,如果它因任何原因失败,我希望能够再次调用“执行”,但这不起作用。我相信这是因为可连接的observable已经完成了。

如何在不必每次都重新创建视图模型的情况下实现此目的?我知道我可以通过使用flatMap将一个简单的执行发布主题转换为userDetailsObservable来实现这一点,但我依赖onCompleted事件来实现其他功能。当发布主题保持活动状态时,onCompleted事件将丢失。

可连接的可观察解决方案

class ViewModel {
    public var userName: Observable<String> {
         self.userDetailsObservable.map {
             return $0["username"]
         }
    }

    public var address: Observable<String> {
         self.userDetailsObservable.map {
             return $0["address"]
         }
    }

    public func execute() {
        self.userDetailsObservable.connect()
    }

    private lazy var userDetailsObservable: ConnectableObservable<JSON> {
        return Observable.create { observer in
            // execute network request
            // assume there is a json object and error object returned
            if error != nil {
                observer.onError(error)
            } else {
                observer.onNext(json)
            }
            observer.onCompleted()
        }.publish()
    }
}

FlatMap解决方案

每次在执行主体上推送事件时,这将执行网络请求。 (execute.onNext())。这里的问题是onCompleted事件在我们正在转换发布主题时丢失了。

class ViewModel {
    public var userName: Observable<String> {
         self.userDetailsObservable.map {
             return $0["username"]
         }
    }

    public var address: Observable<String> {
         self.userDetailsObservable.map {
             return $0["address"]
         }
    }

    public var execute: PublishSubject<Void>()

    private lazy var userDetailsObservable: Observable<JSON> {
        return self.execute.flatMapLatest { _ in
            Observable.create { observer in
                // execute network request
                // assume there is a json object and error object returned
                if error != nil {
                    observer.onError(error)
                } else {
                    observer.onNext(json)
                }
                observer.onCompleted()
            }
        }.share()
   }

1 个答案:

答案 0 :(得分:1)

您应该使用catchError并返回默认值(例如"")。

当您从API收到错误时,需要防止observable被丢弃。