NetworkManager class has fetchData generic function for fetching data from Internet.
class NetworkManager {
func fetchData<T: Decodable>(url: URL) -> AnyPublisher<T, ErrorType> {
URLSession
.shared
.dataTaskPublisher(for: url)
.tryMap { data, _ in
return try JSONDecoder().decode(T.self, from: data)
}
.mapError { error -> ErrorType in
switch error {
case let urlError as URLError:
switch urlError.code {
case .notConnectedToInternet, .networkConnectionLost, .timedOut:
return .noInternetConnection
case .cannotDecodeRawData, .cannotDecodeContentData:
return .empty
default:
return .general
}
default:
return .general
}
}
.eraseToAnyPublisher()
}
}
In HomeRepositoryImpl class I am trying to get data from specific url with AnyPublisher<[CountryDayOneResponse], ErrorType> return value. I wanted to sort responed array, so I used flatMap on NetworkManager like this:
func getCountryStats(for countryName: String) -> AnyPublisher<[CountryDayOneResponse], ErrorType> {
let url = RestEndpoints.countryStats(countryName: countryName).endpoint()
return NetworkManager().fetchData(url: url)
.flatMap { result -> AnyPublisher<[CountryDayOneResponse], ErrorType> in
switch result {
case .success(var response):
let filteredCountry = Array(response.sorted(by: {$0.date > $1.date}))
response = filteredCountry
return response
case .failure(let error):
return error
}
}
.eraseToAnyPublisher()
}
But I am getting Unable to infer type of a closure parameter 'result' in the current context error.
CodePudding user response:
From what I can see in your code... you haven't told it what result
is. Even reading it as a human I can't tell what it is supposed to be.
Your fetchData
function returns an AnyPublisher
of generic type T
.
Your getCountryStats
function takes that generic type T
into a flatMap
function and returns an AnyPublisher
of type [CountryDayOneResponse]
.
But at no point do you tell it what T
is. You don't even tell it what result
is. Only the output of the flatMap
function.
What is the type of result
expected to be?
Edit after comment.
If you want your result
to be [CountryOneDayResponse]
then this code will do...
func getCountryStats(for countryName: String) -> AnyPublisher<[CountryDayOneResponse], ErrorType> {
let url = RestEndpoints.countryStats(countryName: countryName).endpoint()
let publisher: AnyPublisher<[CountryDayOneResponse], ErrorType> = NetworkManager().fetchData(url: url)
return publisher
.flatMap{ Just(Array($0.sorted(by: {$0.date > $1.date}))) }
.eraseToAnyPublisher()
}
You don't need to switch on the result like you are doing in the flatMap
as the flatMap
will only be entered if the publisher returns a non-error. So you can treat the input of the flatMap
as the success type of the publisher [CountryOneDayResponse]
.