在创建可观察对象数组后在 RxSwift 中使用 zip 运算符
Using zip operator in RxSwift after creating an array of observables
我有一个 newBid
对象,其中包含一些数据和图像数组。我想将所有图像和数据上传到服务器,然后 zip
那些上传可观察对象。如果我为 data
、image1
和 image2
创建单独的 drivers
,我就成功了。
但我真正想做的是不对图像进行硬编码,因为数组可能包含 0 到 10 张图像。我想以编程方式创建 observables 数组并 zip
它们。
let dataSaved = saveTaps.withLatestFrom(newBid)
.flatMapLatest { bid in
return CustomerManager.shared.bidCreate(bid: bid)
.trackActivity(activityIndicator)
.asDriver(onErrorJustReturn: false)
}
let photoSaved0 = saveTaps.withLatestFrom(newBid)
.flatMapLatest { bid in
return CustomerManager.shared.bidUploadFile(image: bid.images[0])
.trackActivity(activityIndicator)
.asDriver(onErrorJustReturn: false)
}
let photoSaved1 = saveTaps.withLatestFrom(newBid)
.flatMapLatest { bid in
return CustomerManager.shared.bidUploadFile(image: bid.images[1])
.trackActivity(activityIndicator)
.asDriver(onErrorJustReturn: false)
}
saveCompleted = Driver.zip(dataSaved, photoSaved0, photoSaved1){ return [=10=] && && }
/*
// 0. Getting array of images from newBid
let images = newBid.map { bid in
return bid.images
}
// 1. Creating array of upload drivers from array of images
let imageUploads = images.map { (images: [UIImage]) -> [Driver<Bool>] in
var temp = [Driver<Bool>]()
return temp
}
// 2. Zipping array of upload drivers to photoSaved driver
photoSaved = Driver
.zip(imageUploads) // wait for all image requests to finish
.subscribe(onNext: { results in
// here you have every single image in the 'images' array
results.forEach { print([=10=]) }
})
.disposed(by: disposeBag)*/
在评论部分,如果我尝试 zip
imageUploads,我会收到错误消息:
Argument type 'SharedSequence<DriverSharingStrategy, [SharedSequence<DriverSharingStrategy, Bool>]>' does not conform to expected type 'Collection'
最终解决方案
let bidID: Driver<Int> = saveTaps.withLatestFrom(newBid)
.flatMapLatest { bid in
return CustomerManager.shared.bidCreate(bid: bid)
.trackActivity(activityIndicator)
.asDriver(onErrorJustReturn: 0)
}
saveCompleted = Driver.combineLatest(bidID, newBid) { bidID, newBid in
newBid.uploadedImages.map {
CustomerManager.shared.bidUploadFile(image: [=10=], bidID: bidID).asDriver(onErrorJustReturn: false)
}
}.flatMap { imageUploads in
return Driver.zip(imageUploads).trackActivity(activityIndicator).asDriver(onErrorJustReturn: [])
}.map{ (results:[Bool]) -> Bool in
return !results.contains(false)
}
它是这个的组合版本,等效于:
let imageUploads: Driver<[Driver<Bool>]> = Driver.combineLatest(bidID, newBid) { bidID, newBid in
newBid.uploadedImages.map {
CustomerManager.shared.bidUploadFile(image: [=11=], bidID: bidID).asDriver(onErrorJustReturn: false)
}
}
let photosSaved: Driver<[Bool]> = imageUploads.flatMap { imageUploads in
return Driver.zip(imageUploads).trackActivity(activityIndicator).asDriver(onErrorJustReturn: [])
}
saveCompleted = photosSaved.map{ (results:[Bool]) -> Bool in
return !results.contains(false)
}
这样的怎么样?
let saves = saveTaps.withLatestFrom(newBid)
.flatMapLatest { (bid: Bid) -> Observable<[Bool]> in
let dataSaved = CustomerManager.shared.bidCreate(bid: bid)
.catchErrorJustReturn(false)
let photosSaved = bid.images.map {
CustomerManager.shared.bidUploadFile(image: [=10=], bidID: bid.id)
.catchErrorJustReturn(false)
}
return Observable.zip([dataSaved] + photosSaved)
.trackActivity(activityIndicator)
}
.asDriver(onErrorJustReturn: []) // remove this line if you want an Observable<[Bool]>.
我有一个 newBid
对象,其中包含一些数据和图像数组。我想将所有图像和数据上传到服务器,然后 zip
那些上传可观察对象。如果我为 data
、image1
和 image2
创建单独的 drivers
,我就成功了。
但我真正想做的是不对图像进行硬编码,因为数组可能包含 0 到 10 张图像。我想以编程方式创建 observables 数组并 zip
它们。
let dataSaved = saveTaps.withLatestFrom(newBid)
.flatMapLatest { bid in
return CustomerManager.shared.bidCreate(bid: bid)
.trackActivity(activityIndicator)
.asDriver(onErrorJustReturn: false)
}
let photoSaved0 = saveTaps.withLatestFrom(newBid)
.flatMapLatest { bid in
return CustomerManager.shared.bidUploadFile(image: bid.images[0])
.trackActivity(activityIndicator)
.asDriver(onErrorJustReturn: false)
}
let photoSaved1 = saveTaps.withLatestFrom(newBid)
.flatMapLatest { bid in
return CustomerManager.shared.bidUploadFile(image: bid.images[1])
.trackActivity(activityIndicator)
.asDriver(onErrorJustReturn: false)
}
saveCompleted = Driver.zip(dataSaved, photoSaved0, photoSaved1){ return [=10=] && && }
/*
// 0. Getting array of images from newBid
let images = newBid.map { bid in
return bid.images
}
// 1. Creating array of upload drivers from array of images
let imageUploads = images.map { (images: [UIImage]) -> [Driver<Bool>] in
var temp = [Driver<Bool>]()
return temp
}
// 2. Zipping array of upload drivers to photoSaved driver
photoSaved = Driver
.zip(imageUploads) // wait for all image requests to finish
.subscribe(onNext: { results in
// here you have every single image in the 'images' array
results.forEach { print([=10=]) }
})
.disposed(by: disposeBag)*/
在评论部分,如果我尝试 zip
imageUploads,我会收到错误消息:
Argument type 'SharedSequence<DriverSharingStrategy, [SharedSequence<DriverSharingStrategy, Bool>]>' does not conform to expected type 'Collection'
最终解决方案
let bidID: Driver<Int> = saveTaps.withLatestFrom(newBid)
.flatMapLatest { bid in
return CustomerManager.shared.bidCreate(bid: bid)
.trackActivity(activityIndicator)
.asDriver(onErrorJustReturn: 0)
}
saveCompleted = Driver.combineLatest(bidID, newBid) { bidID, newBid in
newBid.uploadedImages.map {
CustomerManager.shared.bidUploadFile(image: [=10=], bidID: bidID).asDriver(onErrorJustReturn: false)
}
}.flatMap { imageUploads in
return Driver.zip(imageUploads).trackActivity(activityIndicator).asDriver(onErrorJustReturn: [])
}.map{ (results:[Bool]) -> Bool in
return !results.contains(false)
}
它是这个的组合版本,等效于:
let imageUploads: Driver<[Driver<Bool>]> = Driver.combineLatest(bidID, newBid) { bidID, newBid in
newBid.uploadedImages.map {
CustomerManager.shared.bidUploadFile(image: [=11=], bidID: bidID).asDriver(onErrorJustReturn: false)
}
}
let photosSaved: Driver<[Bool]> = imageUploads.flatMap { imageUploads in
return Driver.zip(imageUploads).trackActivity(activityIndicator).asDriver(onErrorJustReturn: [])
}
saveCompleted = photosSaved.map{ (results:[Bool]) -> Bool in
return !results.contains(false)
}
这样的怎么样?
let saves = saveTaps.withLatestFrom(newBid)
.flatMapLatest { (bid: Bid) -> Observable<[Bool]> in
let dataSaved = CustomerManager.shared.bidCreate(bid: bid)
.catchErrorJustReturn(false)
let photosSaved = bid.images.map {
CustomerManager.shared.bidUploadFile(image: [=10=], bidID: bid.id)
.catchErrorJustReturn(false)
}
return Observable.zip([dataSaved] + photosSaved)
.trackActivity(activityIndicator)
}
.asDriver(onErrorJustReturn: []) // remove this line if you want an Observable<[Bool]>.