代码之家  ›  专栏  ›  技术社区  ›  Denis Kutlubaev

在RxSwift中创建一个可观测数组后使用zip运算符

  •  0
  • Denis Kutlubaev  · 技术社区  · 6 年前

    newBid 对象,它包含一些数据和图像数组。我想把所有的图片和数据上传到服务器 zip 那些上传的是可观察到的。如果我创建单独的 drivers 对于 data , image1 image2 ,我成功了。

    但我真正想做的是不要硬编码图像,因为数组可能包含0到10个图像。我想以编程方式创建observables数组 拉链 他们。

    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 $0 && $1 && $2 }
    
    /*
    // 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($0) }
        })
        .disposed(by: disposeBag)*/
    

    如果我试图 图像上传,我得到错误:

    Argument type 'SharedSequence<DriverSharingStrategy, [SharedSequence<DriverSharingStrategy, Bool>]>' does not conform to expected type 'Collection'
    
    2 回复  |  直到 6 年前
        1
  •  1
  •   Daniel T.    6 年前

    像这样的怎么样?

    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: $0, bidID: bid.id)
                    .catchErrorJustReturn(false)
            }
    
            return Observable.zip([dataSaved] + photosSaved)
                .trackActivity(activityIndicator)
        }
        .asDriver(onErrorJustReturn: []) // remove this line if you want an Observable<[Bool]>.
    
        2
  •  0
  •   Denis Kutlubaev    6 年前

    最终解决方案

    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: $0, 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: $0, 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)
    }