繁体   English   中英

RXSwift ObservableCollection 与 CombineLatest

[英]RXSwift ObservableCollection with CombineLatest

我正在尝试实现这样的东西,

    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)

就我而言,我正在尝试动态创建 observable 并将其添加到这样的数组中,

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<A?>

我该如何正确执行此操作,我想确保在开始处理数据之前所有 observable 都返回数据。

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

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

protocol YourProtocol {...}

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

然后你可以:

private var discoverObservables = [Observable<YourProtocol>]() 

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

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

    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]>

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

严格来说,您可能不想要Any结构。 更好的是协议或枚举。 我看到其他答案已经解决了协议的想法,所以我将使用枚举的想法:

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 observable 将包含所有响应的数组。 换句话说, zip操作符将收集来自所有网络调用的所有响应,并发出一个包含所有响应的数组。

我之前的回答:

问题中确实没有很多信息可以继续,但是这样的事情回答了您提出的有关将Observable<X>转换为Observable<Any>的直接问题......

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
        }
    }
)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM