-
-
Save anilabsinc-ajay/6aea8a6bb9f54c20a26419dab0eb334f to your computer and use it in GitHub Desktop.
This file contains hidden or 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
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) | |
} | |
} |
This file contains hidden or 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
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 () } | |
) | |
} | |
} |
This file contains hidden or 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
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