I am trying to develop generic network layer which supports closure, async and combine features.
I want network layer not to depend on any library.
Protocol:
import Combine
import Foundation
protocol NetworkService {
// Closure
func get<ResponseModel>(endpoint: String,
response: ResponseModel.Type,
completion: @escaping (Result<ResponseModel, Error>) -> Void) where ResponseModel: Decodable
// Async
func get<ResponseModel>(endpoint: String,
response: ResponseModel.Type) async -> Result<ResponseModel, Error> where ResponseModel: Decodable
// Combine
func get<ResponseModel>(endpoint: String,
response: ResponseModel.Type) -> AnyPublisher<Result<ResponseModel, Error>, Never> where ResponseModel: Decodable
}
When implementing protocol in Alamofire, i get errors.
Implementation:
import Alamofire
import Combine
import Foundation
final class AlamofireService: NetworkService {
let session: Session
// Encoder and Decoder
let encoder = JSONEncoder()
let decoder = JSONDecoder()
init() {
session = Session()
}
// Closure
func get<ResponseModel>(endpoint: String,
response: ResponseModel.Type,
completion: @escaping (Result<ResponseModel, Error>) -> Void) where ResponseModel: Decodable
{
session
.request(endpoint, method: .get)
.validate()
.responseDecodable(of: response, decoder: decoder) {
completion($0.result)
}
}
// Async
func get<ResponseModel>(endpoint: String,
response: ResponseModel.Type) async -> Result<ResponseModel, Error> where ResponseModel: Decodable
{
let result = await session
.request(endpoint, method: .get)
.validate()
.serializingDecodable(response, decoder: decoder)
.result
return result
}
// Combine
func get<ResponseModel>(endpoint: String,
response: ResponseModel.Type) -> AnyPublisher<Result<ResponseModel, Error>, Never> where ResponseModel: Decodable
{
let result = session
.request(endpoint, method: .get)
.validate()
.publishDecodable(type: response, decoder: decoder)
.result()
return result
}
}
Errors:
Closure: Cannot convert value of type 'Result<ResponseModel, AFError>' to expected argument type 'Result<ResponseModel, any Error>'
Async: Cannot convert return expression of type 'Result<ResponseModel, AFError>' to return type 'Result<ResponseModel, any Error>'
Combine: Cannot convert return expression of type 'AnyPublisher<Result<ResponseModel, AFError>, Never>' to return type 'AnyPublisher<Result<ResponseModel, any Error>, Never>'
My question is how can i convert AFError to Error?
CodePudding user response:
Yes, the compiler just doesn't convert it for you automatically. Easiest way to convert is to use mapError { $0 as Error }
.
await session
.request(endpoint, method: .get)
.validate()
.serializingDecodable(response, decoder: decoder)
.result
.mapError { $0 as Error }