首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >RXSwift ObservableCollection和CombineLatest

RXSwift ObservableCollection和CombineLatest
EN

Stack Overflow用户
提问于 2020-09-22 15:46:55
回答 3查看 812关注 0票数 1

我在努力实现这样的东西,

代码语言:javascript
复制
    let api1 = Observable.of(["documents"])    //Replace with observable to download docs
    let api2 = Observable.of(["applications"]) //Replace with observable to download apps
    let api3 = Observable.of(["videos"])       //Replace with observable to download videos

    Observable.combineLatest(api1, api2, api3){(docs, apps, videos) in
        return (docs, apps, videos)
    }.skipWhile{ (docs, apps, videos) in
        return docs.count == 0 && apps.count == 0 && videos.count == 0
    }.subscribe(onNext:{(docs, apps, videos) in

    })
    .disposed(by:disposeBag)

在我的例子中,我试图动态地创建可观测值并将其添加到这样的数组中,

代码语言:javascript
复制
private var discoverObservables = [Observable<Any>]()


func loadDiscoverFeeds(){
      
        self.feeds.forEach({
            feed in
            switch feed.feedType{
            case "a":
                let observable = self.aObservable(url: feed.feedURL ?? "")
                self.discoverObservables.append(observable)
                break
            case "b":
                let observable = self.bObservable(url: feed.feedURL ?? "")
                self.discoverObservables.append(observable)
                break
            case "c":
                let observable = self.cObservable(url: feed.feedURL ?? "")
                self.discoverObservables.append(observable)
                break
            case "d" :
                let observable = self.dObservable(url: feed.feedURL ?? "")
                self.discoverObservables.append(observable)
                break
            default:
                break
            
            }
        })
}

    private func aObservable(url : String) -> Observable<A?>{
            return APIManager.shared.getA(url: url)
        }

    private func bObservable(url : String) -> Observable<B?>{
            return APIManager.shared.getB(url: url)
        }


    private func cObservable(url : String) -> Observable<C?>{
            return APIManager.shared.getC(url: url)
        }

但是这不起作用,因为discoverObservables数组期望类型Observable<Any>的值,我正在尝试添加Observable<Any>

如何正确地做到这一点,在开始处理数据之前,我希望确保所有可观察到的返回数据。

在将数据添加到视图之前,我尝试从不同的源加载数据,基本上,我有一个集合视图,每个部分从不同的加载数据,在将数据添加到集合视图之前,我尝试从所有源获取所有所需的数据。

EN

回答 3

Stack Overflow用户

发布于 2020-09-23 09:53:48

向A、B和C添加相同的协议。

代码语言:javascript
复制
protocol YourProtocol {...}

class A: YourProtocol {...}
class B: YourProtocol {...}
class C: YourProtocol {...}

然后你可以:

代码语言:javascript
复制
private var discoverObservables = [Observable<YourProtocol>]() 
票数 2
EN

Stack Overflow用户

发布于 2020-09-23 10:25:09

第一个代码块似乎是在做这个工作,除了一个例外,条件检查是否所有(文档、应用程序、视频)都是空的,也许您想使用||而不是&&

至于第二个带有数组的代码块,我做了一些可能有帮助的事情。

代码语言:javascript
复制
    struct A {}
    
    let observable1 = Observable.just(A())
    let observable2 = Observable.just(A())
    let observable3 = Observable.just(A())

    let observables: [Observable<A>] = [observable1, observable2, observable3]
    
    Observable.combineLatest(observables).skipWhile { (streams) -> Bool in
        streams.forEach {
            if $0.count == 0 { return true }
        }
        return false
    }.subscribe(...

此订阅将在Observable<[A]>中产生。

票数 1
EN

Stack Overflow用户

发布于 2020-09-23 12:26:18

我将从您的问题中具体解决这个问题:“在开始处理数据之前,我要确保所有可观察到的返回数据。”

严格地说,您可能不需要Any结构。最好是一份协议或一份文件。我看到其他的答案已经解决了协议的想法,所以我将使用enum的想法:

代码语言:javascript
复制
enum EndpointResponse {
    case a(A?)
    case b(B?)
    // etc...
}

let responses = Observable.zip(
    feeds.map { (feed) -> Observable<EndpointResponse> in
        switch feed.feedType {
        case "a":
            return aObservable(url: feed.feedURL ?? "").map { EndpointResponse.a($0) }
        case "b":
            return bObservable(url: feed.feedURL ?? "").map { EndpointResponse.b($0) }
        default:
            fatalError()
        }
    }
)

上面所观察到的responses将包含所有响应的数组,一旦它们都发出了值。换句话说,zip操作符将收集来自所有网络调用的所有响应,并发出一个包含所有响应的数组。

我以前的答案:

在这个问题中确实没有太多的信息可供讨论,但类似于这样的问题回答了关于将Observable<X>转换为Observable<Any>的直接问题。

代码语言:javascript
复制
let discoverObservables = Observable.zip(
    feeds.map { (feed) -> Observable<Any> in
        switch feed.feedType {
        case "a":
            return aObservable(url: feed.feedURL ?? "").map { $0 as Any }
        case "b":
            return bObservable(url: feed.feedURL ?? "").map { $0 as Any }
        case "c":
            return cObservable(url: feed.feedURL ?? "").map { $0 as Any }
        case "d":
            return dObservable(url: feed.feedURL ?? "").map { $0 as Any }
        default:
            break
        }
    }
)
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64013269

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档