Skip to content

Instantly share code, notes, and snippets.

@anilabsinc-ajay
Forked from kean/Client.swift
Created January 5, 2018 05:46
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 anilabsinc-ajay/6aea8a6bb9f54c20a26419dab0eb334f to your computer and use it in GitHub Desktop.
Save anilabsinc-ajay/6aea8a6bb9f54c20a26419dab0eb334f to your computer and use it in GitHub Desktop.
import Foundation
import Alamofire
import RxSwift
import RxCocoa
protocol ClientProtocol {
func request<Response>(_ endpoint: Endpoint<Response>) -> Single<Response>
}
final class Client: ClientProtocol {
private let manager: Alamofire.SessionManager
private let baseURL = URL(string: "<your_server_base_url>")!
private let queue = DispatchQueue(label: "<your_queue_label>")
init(accessToken: String) {
var defaultHeaders = Alamofire.SessionManager.defaultHTTPHeaders
defaultHeaders["Authorization"] = "Bearer \(accessToken)"
let configuration = URLSessionConfiguration.default
// Add `Auth` header to the default HTTP headers set by `Alamofire`
configuration.httpAdditionalHeaders = defaultHeaders
self.manager = Alamofire.SessionManager(configuration: configuration)
self.manager.retrier = OAuth2Retrier()
}
func request<Response>(_ endpoint: Endpoint<Response>) -> Single<Response> {
return Single<Response>.create { observer in
let request = self.manager.request(
self.url(path: endpoint.path),
method: httpMethod(from: endpoint.method),
parameters: endpoint.parameters
)
request
.validate()
.responseData(queue: self.queue) { response in
let result = response.result.flatMap(endpoint.decode)
switch result {
case let .success(val): observer(.success(val))
case let .failure(err): observer(.error(err))
}
}
return Disposables.create {
request.cancel()
}
}
}
private func url(path: Path) -> URL {
return baseURL.appendingPathComponent(path)
}
}
private func httpMethod(from method: Method) -> Alamofire.HTTPMethod {
switch method {
case .get: return .get
case .post: return .post
case .put: return .put
case .patch: return .patch
case .delete: return .delete
}
}
private class OAuth2Retrier: Alamofire.RequestRetrier {
func should(_ manager: SessionManager, retry request: Request, with error: Error, completion: @escaping RequestRetryCompletion) {
if (error as? AFError)?.responseCode == 401 {
// TODO: implement your Auth2 refresh flow
// See https://github.com/Alamofire/Alamofire#adapting-and-retrying-requests
}
completion(false, 0)
}
}
import Foundation
// MARK: Defines
typealias Parameters = [String: Any]
typealias Path = String
enum Method {
case get, post, put, patch, delete
}
// MARK: Endpoint
final class Endpoint<Response> {
let method: Method
let path: Path
let parameters: Parameters?
let decode: (Data) throws -> Response
init(method: Method = .get,
path: Path,
parameters: Parameters? = nil,
decode: @escaping (Data) throws -> Response) {
self.method = method
self.path = path
self.parameters = parameters
self.decode = decode
}
}
// MARK: Convenience
extension Endpoint where Response: Swift.Decodable {
convenience init(method: Method = .get,
path: Path,
parameters: Parameters? = nil) {
self.init(method: method, path: path, parameters: parameters) {
try JSONDecoder().decode(Response.self, from: $0)
}
}
}
extension Endpoint where Response == Void {
convenience init(method: Method = .get,
path: Path,
parameters: Parameters? = nil) {
self.init(
method: method,
path: path,
parameters: parameters,
decode: { _ in () }
)
}
}
import Foundation
// MARK: Defining Endpoints
enum API {}
extension API {
static func getCustomer() -> Endpoint<Customer> {
return Endpoint(path: "customer/profile")
}
static func patchCustomer(name: String) -> Endpoint<Customer> {
return Endpoint(
method: .patch,
path: "customer/profile",
parameters: ["name" : name]
)
}
}
final class Customer: Decodable {
let name: String
}
// MARK: Using Endpoints
func test() {
let client = Client(accessToken: "<access_token>")
_ = client.request(API.getCustomer())
_ = client.request(API.patchCustomer(name: "Alex"))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment