Last active
August 21, 2019 10:37
-
-
Save akhtarraza/f2fe63a8921815b2605fa1b1c785b5b6 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
import Alamofire | |
public class AuthSessionManager { | |
static var sharedManager = AuthSessionManager() | |
public var sessionManager: SessionManager | |
private init() { | |
let serverTrustPolicy = ServerTrustPolicy.pinCertificates ( | |
certificates: ServerTrustPolicy.certificates(), | |
validateCertificateChain: true, | |
validateHost: true | |
) | |
let manager = ServerTrustPolicyManager(policies: [ | |
"*.google.com" : serverTrustPolicy, | |
"*.dev.apple.com":.disableEvaluation | |
]) | |
let configuration = URLSessionConfiguration.default | |
configuration.httpAdditionalHeaders = SessionManager.defaultHTTPHeaders | |
self.sessionManager = SessionManager(configuration: configuration, serverTrustPolicyManager: manager) | |
} | |
} |
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
import Alamofire | |
public class XauthHeadersAdapter: RequestAdapter { | |
public let authUserId: String? | |
public let authToken: String? | |
var additionalHeaders:Parameters? | |
init(userId: String? = nil, token: String? = nil) { | |
authUserId = userId | |
authToken = token | |
} | |
public func adapt(_ urlRequest: URLRequest) throws -> URLRequest { | |
var requestWithAuthHeaders = urlRequest | |
if let userId = authUserId { | |
requestWithAuthHeaders.setValue(userId, forHTTPHeaderField: "X-Auth-UID") | |
} | |
if let token = authToken { | |
requestWithAuthHeaders.setValue(token, forHTTPHeaderField: "X-Auth-Token") | |
} | |
if let moreHeaders = self.additionalHeaders { | |
for item in moreHeaders { | |
requestWithAuthHeaders.setValue(item.value as? String ?? "", forHTTPHeaderField: item.key) | |
} | |
} | |
return requestWithAuthHeaders | |
} | |
} |
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
import Alamofire | |
import SwiftyJSON | |
import PromiseKit | |
public typealias APIResponse = (data:JSON?, error:Error?) | |
public typealias Parameters = [String: Any] | |
typealias Path = String | |
typealias Method = Alamofire.HTTPMethod | |
final class Endpoint { | |
let method: HTTPMethod | |
let path: Path | |
let parameters: Parameters? | |
let headers: HTTPHeaders? | |
let encoding: ParameterEncoding | |
init(method: HTTPMethod = .get, | |
path:Path, | |
parameters: Parameters? = nil, | |
headers: HTTPHeaders? = nil, | |
encoding: ParameterEncoding = URLEncoding.default) { | |
self.method = method | |
self.path = path | |
self.parameters = parameters | |
self.headers = headers | |
self.encoding = encoding | |
} | |
} | |
protocol WebClient { | |
func request(_ endpoint: Endpoint, completionBlock:@escaping(APIResponse) -> ()) | |
} | |
public enum WebServiceError: Error { | |
case invalidResponse(message: String?) | |
case authError | |
} | |
extension WebServiceError: LocalizedError { | |
public var errorDescription: String? { | |
switch self { | |
case.invalidResponse(let message): | |
return message ?? "Unknown error occured" | |
case .authError: | |
return "Your session has timedout, Please re-login to continue." | |
} | |
} | |
} | |
final class APIClient: WebClient { | |
private let sessionManger = AuthSessionManager.sharedManager | |
private let adapter: RequestAdapter? | |
init(adapter:XauthHeadersAdapter? = nil) { | |
self.manager.sessionManager.retrier = OAuth2Retrier() | |
self.adapter = adapter | |
} | |
func url(path: Path) -> URL { | |
return URL(string: path)! | |
} | |
func request(_ endpoint: Endpoint, completionBlock:@escaping(APIResponse) -> ()) { | |
self.manager.sessionManager.adapter = self.adapter | |
let requestObj = manager.sessionManager.request(self.url(path: endpoint.path), method:endpoint.method, parameters: endpoint.parameters, encoding: endpoint.encoding, headers:endpoint.headers) | |
.responseJSON(queue: DispatchQueue.init(label: "com.webclient.jsonparser"), options: .mutableLeaves) { response in | |
switch response.result { | |
case .success(let val): | |
print("Response : ",JSON(val)) | |
if JSON(val)["code"] == 401 { | |
print("Auth error, 401 recieved.") | |
completionBlock((nil, WebServiceError.authError)) | |
} else { | |
completionBlock((JSON(val), nil)) | |
} | |
case .failure(let error): | |
print(error) | |
completionBlock((nil, WebServiceError.invalidResponse(message: "Sorry, app had an error. Please try after some time.")) | |
} | |
} | |
debugPrint(requestObj) | |
} | |
func request(_ endpoint:Endpoint) -> Promise<JSON> { | |
self.manager.sessionManager.adapter = adapter | |
return Promise<APIResponse> { seal in | |
let request = manager.sessionManager.request(self.url(path: endpoint.path), method: endpoint.method, parameters: endpoint.parameters, encoding: endpoint.encoding, headers: endpoint.headers) | |
request.responseJSON() | |
.tap { | |
debugPrint(request) | |
print($0) | |
}.done { (json, response) in | |
//Check for auth error code 401 | |
let jsonData = JSON(json) | |
if jsonData["code"] == 401 { | |
seal.reject(WebServiceError.authError) | |
} else { | |
seal.fulfill(jsonData) | |
} | |
}.catch { error in | |
debugPrint(request) | |
debugPrint(error) | |
seal.reject(WebServiceError.invalidResponse(message: "Sorry, app had an error. Please try after some time.")) | |
} | |
} | |
} | |
} | |
private class OAuth2Retrier: Alamofire.RequestRetrier { | |
func should(_ manager: SessionManager, retry request: Request, with error: Error, completion: @escaping RequestRetryCompletion) { | |
if (error as? AFError)?.responseCode == 401 { | |
print(error.localizedDescription) | |
} | |
completion(false, 0) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment