无法推断复杂的闭包返回类型;在RxSwift中添加显式类型以消除歧义

时间:2018-09-05 09:47:11

标签: swift rx-swift flatmap

我需要打多个电话。

1。删除文档上传

2。图片1和服务器返回URL

3。上传图片2和服务器返回URL

4。创建文档API既包含URL又包含额外的
        参数。

我尝试编写的代码是在RxSwift和MVVM中。

  let resultOfDocumentUpdateWithDelete =
            donepressed
                .filter{ $0 }
                .withLatestFrom(self.existingDocumentIDChangedProperty)
                .flatMapLatest {id in
                    let deleted_document = apiClient.deleteDocument(id).asObservable().materialize()
                    let upload_frontImage = deleted_document
                        .withLatestFrom(self.frontImageNameChangedProperty)
                        .flatMapLatest {image in
                            apiClient.uploadImage(image: image!).asObservable().materialize()
                    }
                    let upload_backImage = upload_frontImage
                        .withLatestFrom(self.backImageChangedProperty)
                        .flatMapLatest {image in
                            apiClient.uploadImage(image: image!).asObservable().materialize()
                    }

                    let upload_document = upload_backImage
                        .withLatestFrom(self.parametersChangedProperty)
                        .flatMapLatest {parameters in
                            apiClient.uploadDocument(parameters: parameters)
                    }

                    return upload_document.materialize()
                }
                .share(replay: 1)

请确保在最后一个API中输入了服务器的两个响应,因此将依次调用所有这些响应。

如何在RxSwift中进行操作。

1 个答案:

答案 0 :(得分:1)

这很有趣!这里的要点是,当您有疑问时,请继续进行自己的操作。如果事实证明您以后又想出了如何使用内置运算符来完成这项工作,则可以替换您的运算符。自己做的唯一一件事就是他们需要更多的测试。

请注意,要使用以下内容,您必须先组合最新的可观察对象,然后再组合flatMap并将其值传递给此函数。

// all possible results from this job.
enum ProcessResult {
    case success
    case deleteFailure(Error)
    case imageFailue(Error)
    case backImageFailure(Error)
    case documentFailure(Error)
}

func uploadContent(apiClient: APIClient, documentID: Int, frontImage: UIImage, backImage: UIImage, parameters: Parameters) -> Single<ProcessResult> {
    // instead of trying to deal with all the materializes, I decided to turn it into a single process.
    return Single.create { observer in

        // each api call happens in turn. Note that there are no roll-back semantics included! You are dealing with a very poorly written server.
        let deleted = apiClient.deleteDocument(id: documentID)
            .asObservable()
            .share()

        let imagesUploaded = deleted
            .flatMap { _ in Observable.zip(apiClient.uploadImage(image: frontImage).asObservable(), apiClient.uploadImage(image: backImage).asObservable()) }
            .share()

        let documentUploaded = imagesUploaded
            .flatMap { arg -> Single<Void> in
                let (frontURL, backURL) = arg
                var updatedParams = parameters
                // add frontURL and backURL to parameters
                return apiClient.uploadDocument(parameters: updatedParams)
            }
            .share()

        let disposable = deleted
            .subscribe(onError: { observer(.success(ProcessResult.deleteFailure($0))) })
        let disposable1 = imagesUploaded
            .subscribe(onError: { observer(.success(ProcessResult.imageFailue($0))) })
        let disposable2 = documentUploaded
            .subscribe(
                onNext: { observer(.success(ProcessResult.success)) },
                onError: { observer(.success(ProcessResult.documentFailure($0))) }
        )

        return Disposables.create([disposable, disposable1, disposable2])
    }
}