Skip to content

Instantly share code, notes, and snippets.

@agiguere
Last active August 24, 2020 23:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save agiguere/11b81c826bedf499d1acd3a68f02c2cf to your computer and use it in GitHub Desktop.
Save agiguere/11b81c826bedf499d1acd3a68f02c2cf to your computer and use it in GitHub Desktop.
SAPURLSession+Extension for SAP Blog
import Foundation
import SAPFoundation
import Combine
public extension SAPURLSession {
enum SAPURLError: Error {
case requestFailed(URLError)
case redirection(HTTPURLResponse)
case client(response: HTTPURLResponse, payload: ODataErrorPayload?)
case server(HTTPURLResponse)
case unknown
init(_ error: Error) {
switch error {
case is URLError:
self = .requestFailed(error as! URLError)
case is SAPURLError:
self = error as! SAPURLError
default:
self = .unknown
}
}
}
func getImage(for url: URL) -> AnyPublisher<UIImage, SAPURLError> {
dataTaskPublisher(for: url)
.tryMap(mapResponseToImage)
.mapError(SAPURLError.init)
.eraseToAnyPublisher()
}
func getImage(for request: URLRequest) -> AnyPublisher<UIImage, SAPURLError> {
dataTaskPublisher(for: request)
.tryMap(mapResponseToImage)
.mapError(SAPURLError.init)
.eraseToAnyPublisher()
}
}
// MARK: - Private API
private extension SAPURLSession {
func mapResponseToImage(transform: (data: Data, response: URLResponse)) throws -> UIImage {
guard let httpResponse = transform.response as? HTTPURLResponse else {
throw SAPURLError.unknown
}
// 2XX Success
if 200...299 ~= httpResponse.statusCode {
return UIImage(data: transform.data)!
// 3XX Redirection
} else if 300...399 ~= httpResponse.statusCode {
throw SAPURLError.redirection(httpResponse)
// 4XX Client Errors
} else if 400...499 ~= httpResponse.statusCode {
throw SAPURLError.client(response: httpResponse, payload: decodeResponse(data: transform.data))
// 5XX Server Errors
} else if 500...599 ~= httpResponse.statusCode {
throw SAPURLError.server(httpResponse)
} else {
throw SAPURLError.unknown
}
}
func decodeResponse(data: Data) -> ODataErrorPayload? {
try? JSONDecoder().decode(ODataErrorPayload.self, from: data)
}
}
// MARK: - LocalizedError (Adapt to your needs)
extension SAPURLSession.SAPURLError: LocalizedError {
public var errorDescription: String? {
switch self {
case .requestFailed(_):
return "RequestError".localized()
case .redirection(_):
return "httpRedirectionError".localized()
case .client(response: _, payload: let payload):
if let payload = payload {
return payload.error.message.value
} else {
return "httpClientError".localized()
}
case .server(_):
return "httpServerError".localized()
case .unknown:
return "UnknownError".localized()
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment