我正在尝试实现类似的东西,
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数组期望使用类型Observable<Any>
的值,并且我试图添加 Observable
如何正确执行此操作,我想确保所有可观察对象在开始处理数据之前都返回数据。
修改 我试图从不同来源加载数据,然后再添加到视图中,基本上,我有一个collectionview,每个部分都从不同的API加载数据,我试图从所有来源获取所有必需的数据,然后再添加到集合中视图。
答案 0 :(得分:1)
向A,B和C添加相同的协议。
protocol YourProtocol {...}
class A: YourProtocol {...}
class B: YourProtocol {...}
class C: YourProtocol {...}
然后您可以创建:
private var discoverObservables = [Observable<YourProtocol>]()
答案 1 :(得分:1)
第一个代码块似乎正在执行此操作,但有一个例外,条件检查所有(文档,应用,视频)是否为空,也许您想使用||
而不是{{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(...
。
答案 2 :(得分: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()
}
}
)
上面的responses
可观察值将包含所有响应的数组,一旦它们具有所有发出的值。换句话说,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
}
}
)