this question is straight forward :
My code :
return urlSession.dataTaskPublisher(for: urlRequest)
.tryMap { (data: Data, response: URLResponse) -> Data in
//TODO: hide loader
GRP.hideLoader()
if let httpURLResponse = response as? HTTPURLResponse {
if !(200...299 ~= httpURLResponse.statusCode) {
var error = NetworkingError(errorCode: httpURLResponse.statusCode)
if let json = try? JSONSerialization.jsonObject(with: data, options: []) {
error.jsonPayload = json
}
throw error
}
}
if withErrorMessage, let errorCheckModel = try? JSONDecoder().decode(ErrorModel.self, from: data)
{
if let statusIsSuccess = errorCheckModel.success, let errorMessage = errorCheckModel.message, !errorMessage.isEmpty
{
if(!statusIsSuccess)
{
print(urlString)
GRP.showToast(failure: true, message: errorMessage)
}
}
}
return data
}.mapError { error -> NetworkingError in
return NetworkingError(error: error)
}
.decode(type: T.self, decoder: decoder)
.receive(on: RunLoop.main)
.eraseToAnyPublisher()
}
i made this task buikder but i am stuck, i want to know how can i implement refresh token i. Thank you.
The question is kind of confusing as written. Do you mean I have a request that returns an AnyPublisher<SomeDecodable, NetworkError>
and if it fails for a specific reason then I want to make another call (to refresh) and then retry the request? If so it looks something like this:
let authenticatedRequest = URLSession.shared.dataTaskPublisher(for: urlRequest)
return authenticatedRequest
.map { (data, response) -> AnyPublisher<(Data, URLResponse), Error> in
isUnanthenticated(response)
? refetchToken.map { _ in
authenticatedRequest
}
.switchToLatest()
.eraseToAnyPublisher()
: Just((data, response)).eraseToAnyPublisher()
}
.switchToLatest()
.decode(T.self, from: decoder)
.mapError { error -> NetworkingError in
return NetworkingError(error: error)
}
.eraseToAnyPublisher()
}