Last active
May 26, 2020 10:21
-
-
Save vani2/a82f490c81441ba33ae3f01369a5c73d to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Services Layer | |
final class EntityService: APIService, EntityServiceProtocol { | |
typealias EntityCompletion = (Result<Entity, Error>) -> Void | |
@discardableResult | |
func createEntity(_ entity: Entity, completion: @escaping EntityCompletion) -> Progress { | |
let endpoint = CreateEntityEndpoint(entity: entity) | |
return apiClient.request(endpoint, completionHandler: completion) | |
} | |
} | |
// APIClient Library | |
public final class Client { | |
public func request<T>(_ endpoint: T, completionHandler: @escaping (Result<T.Content>) -> Void) -> Progress where T: Endpoint { | |
let anyRequest = AnyRequest(create: endpoint.makeRequest) | |
// Alamofire Session Manager | |
let request = sessionManager.request(anyRequest).responseData { (response: DataResponse<Data>) in | |
let result = APIResult<T.Content>(catching: { () throws -> T.Content in | |
let data = try response.result.unwrap() | |
return try endpoint.content(from: response.response, with: data) | |
}) | |
// outside can log errors remotely to analytics service or our own backend API | |
self?.responseObserver?(response.request, response.response, response.data, result.error) | |
completionHandler(result) | |
} | |
return progress(for: request) | |
} | |
} | |
class BaseEndpoint { | |
var encoder: JSONEncoder { return JSONEncoder.default } | |
public func content(from response: URLResponse?, with body: Data) throws -> Content { | |
try responseValidator.validate(response, with: body) | |
let resource = try JSONDecoder.default.decode(ResponseData<Root>.self, from: body) | |
return content(from: resource.data) | |
} | |
} | |
class ResponseValidator { | |
internal func validate(_ response: URLResponse?, with body: Data) throws { | |
try validateAPIResponse(response, with: body) | |
try validateHTTPStatus(response) | |
} | |
private func validateAPIResponse(_ response: URLResponse?, with body: Data) throws { | |
//throws ResponseError or APIError | |
} | |
private func validateHTTPStatus(_ response: URLResponse?) throws { | |
//throws HTTPError | |
} | |
} | |
// Presentation Layer | |
final class EntityViewController: UIViewController, ErrorPresentable { | |
private let entityService: EntityServiceProtocol | |
func createNewEntity(_ entity: Entity) { | |
startLoading() | |
entityService.createEntity(entity) { [weak self] (result: Result<Entity, Error>) in | |
guard let self = self else { return } | |
self.stopLoading() | |
switch result { | |
case .success(let newInterKey): | |
// do business | |
case .failure(let error): | |
self.showError(error) | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment