1

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

    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)

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

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 数组期望 Type 的值,Observable<Any>我正在尝试添加Observable<A?>

我怎样才能正确地做到这一点,我想在我开始处理数据之前确保所有的 observables 都返回数据。

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

4

3 回答 3

1

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

protocol YourProtocol {...}

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

然后你可以制作:

private var discoverObservables = [Observable<YourProtocol>]() 
于 2020-09-23T09:53:48.387 回答
1

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

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

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

于 2020-09-23T10:25:09.513 回答
1

我将从您的问题中专门解决这个问题:“我想确保在开始处理数据之前所有可观察对象都返回数据。”

严格来说,你可能不想要一个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()
        }
    }
)

上面的responsesobservable 将包含所有响应的数组,一旦它们具有所有发出的值。换句话说,zip操作员将收集来自所有网络调用的所有响应,并发出一个包含所有响应的数组。

我之前的回答:

问题中确实没有太多信息可以继续,但是这样的事情回答了您提出的关于将 an 转换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
        }
    }
)
于 2020-09-23T12:26:18.940 回答