如何在Combine中重构将泛型类型化结果转换为Solid结构



我有一个丑陋的结构,将泛型类型作为实体模型返回,有人想重构得更具声明性吗?

extension NetworkingService {

func login(email: String, password: String) -> AnyPublisher<UserModel, APIError> {
func convertToModel() -> AnyPublisher<ResponseObject<UserResponse>, APIError> {
return request(with: AuthRequests.login(email: email, password: password)).eraseToAnyPublisher()
}
return convertToModel().map { UserModel(with: $0.data!) }.eraseToAnyPublisher()
}

func request<T>(with endpoint: Endpoint) -> AnyPublisher<T, APIError> where T : Decodable {
//... returning any publisher with Decodable
}
}

request<T>(with:)函数只在返回中使用T。尽管这是可行的,但这意味着调用代码必须调用T,这就是使您的调用代码";丑陋";。

我从你发布的内容中得到的印象是,你的Endpoint类型唯一能做的就是创建URLRequest。如果它还定义了预期返回数据的形状,那么整个构造将更干净。

我建议让你的Endpoint类型看起来像这样:

public struct Endpoint<Response> {
public let request: URLRequest
public let response: (Data) throws -> Response
public init(request: URLRequest, response: @escaping (Data) throws -> Response) {
self.request = request
self.response = response
}
}

然后,在其他地方进行适当的更新,你可以做这样的事情:

extension NetworkingService {
func login(email: String, password: String) -> AnyPublisher<UserModel, APIError> {
request(with: AuthRequests.login(email: email, password: password))
.map { $0.response.model }
.eraseToAnyPublisher()
}
func request<T>(with endpoint: Endpoint<T>) -> AnyPublisher<T, APIError> where T: Decodable {
//... returning any publisher with Decodable
}
}

最新更新