swift 在通用Publisher上使用flatMap会导致编译错误

np8igboo  于 2023-01-25  发布在  Swift
关注(0)|答案(1)|浏览(153)

我正在编写一个转换函数,它将获取网络请求结果,并尝试使用dict to Model转换器(由于一些后端原因,无法解码)自动解析它们。

func getModel -> Single<Model> {
   return networkRequest(requestParameters).parse(modelTranslator)
}

转换器是通用协议:

public protocol Translator {
    associatedtype Model
    func translateFrom(dictionary json: [String: Any]) throws -> Model
}

Single是Deferred和Future的 Package 器:

public typealias Single<T> = Deferred<Future<T, Error>>

这里有问题的解析扩展方法是:

public extension Publisher {
    func parse<T: Translator, M>(translator: T) -> Single<M> where T.Model == M {
        return self.flatMap { (data: Data) -> Single<M> in
            return Deferred {
                return Future<M, any Error> { promise in
                    guard
                        let json = try? JSONSerialization.jsonObject(with: data, options: []),
                        let dict = json as? [String : Any]
                    else {
                        let error: any Error = TranslatorError.invalidJSONObject
                        return promise(Result.failure(error))
                    }
                    do {
                        let translatedModel: M = translator.translateFrom(dictionary: dict)
                        return promise(Result.success(translatedModel))
                    } catch let error {
                        return promise(Result.failure(error))
                    }
                }
            }
        }
    }
}

它无法编译。它在.flatmap行上显示了2个错误:
1.没有“flatMap”候选项生成预期的上下文结果类型“Single”(也称为“Deferred〈Future〈M,any Error〉〉”)
1.调用示例方法“flatMap”时没有完全匹配
我相信这与类型不匹配有关。你能帮我看看问题吗?
先谢谢你!

rslzwgfq

rslzwgfq1#

您太努力了。您只需要一个简单的tryMap就可以解析您的[String:Any]转换为适当的模型类型。下面是一个完整的示例:

func getFoo(_ requestParameters: RequestParameters) -> AnyPublisher<Foo, Error> {
    getModel(requestParameters, modelTranslator: FooTranslator())
}

func getModel<T>(_ requestParameters: RequestParameters, modelTranslator: T) -> AnyPublisher<T.Model, Error> where T: Translator {
    networkRequest(requestParameters)
        .tryMap { try modelTranslator.translateFrom(dictionary: $0) }
        .eraseToAnyPublisher()
}

以上假设声明如下:

func networkRequest(_ params: RequestParameters) -> Single<[String: Any]> ...

struct FooTranslator: Translator {
    func translateFrom(dictionary json: [String : Any]) throws -> Foo ...
}

相关问题