Created
August 21, 2017 19:44
-
-
Save w-k-s/da8a2a14c56204508a46c33ae631c62a to your computer and use it in GitHub Desktop.
APIRequest
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
// | |
// APIRequest.swift | |
// Asfour | |
// | |
// Created by Waqqas Sheikh on 20/08/2017. | |
// Copyright © 2017 Waqqas Sheikh. All rights reserved. | |
// | |
import Foundation | |
enum APIServerMode{ | |
case uat | |
case live | |
} | |
protocol APISessionDelegate : class{ | |
func sessionTimedOut(request: APIRequest?) | |
} | |
class APIRequest{ | |
let urlSessionTask : URLSessionTask | |
private init(urlSessionTask: URLSessionTask){ | |
self.urlSessionTask = urlSessionTask | |
} | |
class func request(withBuilder builder: APIRequestBuilder)->APIRequest?{ | |
guard let url = APIRequest.buildURL(builder: builder) else {return nil} | |
let request = APIRequest.buildRequest(url: url, builder: builder) | |
let session = URLSession(configuration: .default) | |
let urlSessionTask = session.dataTask(with: request) { (data, urlResponse, error) in | |
APIRequest.log(request: request) | |
let httpUrlResponse = urlResponse as? HTTPURLResponse | |
APIRequest.log(data: data,response: httpUrlResponse,error: error) | |
if(httpUrlResponse?.statusCode == 401){ | |
builder.sessionTimeoutDelegate?.sessionTimedOut(request: APIRequest.request(withBuilder: builder)) | |
return | |
} | |
DispatchQueue.main.async { | |
builder.completionHandler(data,httpUrlResponse,error) | |
} | |
} | |
return APIRequest(urlSessionTask: urlSessionTask) | |
} | |
class func buildURL(builder: APIRequestBuilder)->URL?{ | |
let components = NSURLComponents() | |
components.scheme = "https" | |
components.host = "asfour-quizzical.appspot.com" | |
components.path = "/api/v2\(builder.path)" | |
components.queryItems = builder.queryItems | |
return components.url | |
} | |
class func buildRequest(url: URL,builder: APIRequestBuilder)->URLRequest{ | |
let request = NSMutableURLRequest() | |
var allHeaders = builder.headers | |
if let token = builder.token{ | |
allHeaders["Authorization"] = "bearer \(token)" | |
} | |
request.cachePolicy = builder.cachePolicy | |
request.timeoutInterval = builder.timeout | |
request.httpMethod = builder.method | |
request.url = url | |
request.allHTTPHeaderFields = allHeaders | |
request.httpBody = builder.body | |
return request as URLRequest | |
} | |
class func log(request: URLRequest){ | |
let urlString = request.url?.absoluteString ?? "" | |
let components = NSURLComponents(string: urlString) | |
let method = request.httpMethod != nil ? "\(request.httpMethod!)": "" | |
let path = "\(components?.path ?? "")" | |
let query = "\(components?.query ?? "")" | |
let host = "\(components?.host ?? "")" | |
var requestLog = "\n---------- OUT ---------->\n" | |
requestLog += "\(urlString)" | |
requestLog += "\n\n" | |
requestLog += "\(method) \(path)?\(query) HTTP/1.1\n" | |
requestLog += "Host: \(host)\n" | |
for (key,value) in request.allHTTPHeaderFields ?? [:] { | |
requestLog += "\(key): \(value)\n" | |
} | |
if let body = request.httpBody{ | |
requestLog += "\n\(NSString(data: body, encoding: String.Encoding.utf8.rawValue)!)\n" | |
} | |
requestLog += "\n------------------------->\n"; | |
print(requestLog) | |
} | |
class func log(data: Data?, response: HTTPURLResponse?, error: Error?){ | |
let urlString = response?.url?.absoluteString ?? "" | |
let components = NSURLComponents(string: urlString) | |
let statusCode = "\(response?.statusCode ?? 0)" | |
let path = "\(components?.path ?? "")" | |
let query = "\(components?.query ?? "")" | |
let host = "\(components?.host ?? "")" | |
var responseLog = "\n<---------- IN ----------\n" | |
responseLog += "\(urlString)" | |
responseLog += "\n\n" | |
responseLog += "HTTP/1.1 \(statusCode) \(path)?\(query)\n" | |
responseLog += "Host: \(host)\n" | |
for (key,value) in response?.allHeaderFields ?? [:] { | |
responseLog += "\(key): \(value)\n" | |
} | |
if let body = data{ | |
responseLog += "\n\(NSString(data: body, encoding: String.Encoding.utf8.rawValue)!)\n" | |
} | |
if error != nil{ | |
responseLog += "\nError: \(error!.localizedDescription)\n" | |
} | |
responseLog += "<------------------------\n"; | |
print(responseLog) | |
} | |
func resume(){ | |
self.urlSessionTask.resume() | |
} | |
func cancel(){ | |
self.urlSessionTask.cancel() | |
} | |
} | |
public class APIRequestBuilder{ | |
let method: String | |
let path: String | |
let completionHandler:(Data?,HTTPURLResponse?,Error?)->()? | |
var timeout: TimeInterval = 60 | |
var cachePolicy:NSURLRequest.CachePolicy = .useProtocolCachePolicy | |
var queryItems : [URLQueryItem]? | |
var body : Data? | |
var token: String? | |
var locale: String? | |
var serverMode: APIServerMode = .live | |
var headers : [String:String] = [:] | |
weak var sessionTimeoutDelegate: APISessionDelegate? | |
init(method: String, path: String,completionHandler: @escaping (Data?,HTTPURLResponse?,Error?)->()){ | |
self.method = method; | |
self.path = path; | |
self.completionHandler = completionHandler; | |
} | |
func bodyWithParams(params: [String:String]){ | |
var bodyData = "" | |
for (key,value) in params{ | |
let scapedKey = key.addingPercentEncoding(withAllowedCharacters: | |
.urlHostAllowed)! | |
let scapedValue = value.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed)! | |
bodyData += "\(scapedKey)=\(scapedValue)&" | |
} | |
self.body = bodyData.data(using: .utf8, allowLossyConversion: true) | |
} | |
func build()-> APIRequest?{ | |
return APIRequest.request(withBuilder: self) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment