Skip to content

Instantly share code, notes, and snippets.

@w-k-s
Created August 21, 2017 19:44
Show Gist options
  • Save w-k-s/da8a2a14c56204508a46c33ae631c62a to your computer and use it in GitHub Desktop.
Save w-k-s/da8a2a14c56204508a46c33ae631c62a to your computer and use it in GitHub Desktop.
APIRequest
//
// 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