Created
May 3, 2018 22:34
-
-
Save RxDx/1819bae2e6da2c11f74815d313943daf 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
// | |
// RestAPI.swift | |
// RestAPI | |
// | |
// Created by Rodrigo Dumont on 25/04/18. | |
// | |
open class RestAPI<T: Codable> { | |
public typealias Then = (T?, Error?) -> () | |
public typealias ThenList = ([T]?, Error?) -> () | |
enum Action { | |
case create | |
case delete | |
case getOne | |
case getList | |
case put | |
} | |
let baseURL: String | |
let path: String | |
public var header: [String: String] = [ | |
"Accept":"application/json", | |
"Content-Type":"application/json" | |
] | |
public var showLog: Bool = true | |
public init(baseURL: String, | |
path: String) { | |
self.baseURL = baseURL | |
self.path = path | |
} | |
public func all(then: @escaping ThenList) { | |
debugLog(action: .getList) | |
guard let url = URL(string: "\(baseURL)\(path)") else { | |
then(nil, NSError(domain:"", code:420, userInfo:nil)) | |
return | |
} | |
let urlRequest = createUrlRequest(for: url, header: header) | |
let task = URLSession.shared.dataTask(with: urlRequest) {(data, response, error) in | |
if let error = error { | |
then(nil, error) | |
return | |
} | |
guard let data = data else { | |
then(nil, NSError(domain:"", code:420, userInfo:nil)) | |
return | |
} | |
do { | |
let decoded = try JSONDecoder().decode([T].self, from: data) | |
then(decoded, error) | |
} catch { | |
then(nil, error) | |
} | |
} | |
task.resume() | |
} | |
public func create(_ object: T, then: @escaping Then) { | |
debugLog(action: .create) | |
guard let url = URL(string: "\(baseURL)\(path)") else { | |
then(nil, NSError(domain:"", code:420, userInfo:nil)) | |
return | |
} | |
var urlRequest = createUrlRequest(for: url, header: header) | |
urlRequest.httpMethod = "POST" | |
urlRequest.httpBody = try? JSONEncoder().encode(object) | |
let task = URLSession.shared.dataTask(with: urlRequest) {(data, response, error) in | |
if let error = error { | |
then(nil, error) | |
return | |
} | |
then(nil, nil) | |
} | |
task.resume() | |
} | |
public func delete(id: Int, then: @escaping Then) { | |
debugLog(action: .delete) | |
guard let url = URL(string: "\(baseURL)\(path)/\(id)") else { | |
then(nil, NSError(domain:"", code:420, userInfo:nil)) | |
return | |
} | |
var urlRequest = createUrlRequest(for: url, header: header) | |
urlRequest.httpMethod = "DELETE" | |
let task = URLSession.shared.dataTask(with: urlRequest) {(data, response, error) in | |
if let error = error { | |
then(nil, error) | |
return | |
} | |
then(nil, nil) | |
} | |
task.resume() | |
} | |
public func find(id: Int, then: @escaping Then) { | |
debugLog(action: .getOne) | |
guard let url = URL(string: "\(baseURL)\(path)/\(id)") else { | |
then(nil, NSError(domain:"", code:420, userInfo:nil)) | |
return | |
} | |
let urlRequest = createUrlRequest(for: url, header: header) | |
let task = URLSession.shared.dataTask(with: urlRequest) {(data, response, error) in | |
self.debugLog(data: data, response: response, error: error) | |
if let error = error { | |
then(nil, error) | |
return | |
} | |
guard let data = data else { | |
then(nil, NSError(domain:"", code:420, userInfo:nil)) | |
return | |
} | |
do { | |
let decoded = try JSONDecoder().decode(T.self, from: data) | |
then(decoded, error) | |
} catch { | |
then(nil, error) | |
} | |
} | |
task.resume() | |
} | |
public func update(_ object: T, then: @escaping Then) { | |
debugLog(action: .put) | |
guard let url = URL(string: "\(baseURL)\(path)") else { | |
then(nil, NSError(domain:"", code:420, userInfo:nil)) | |
return | |
} | |
var urlRequest = createUrlRequest(for: url, header: header) | |
urlRequest.httpMethod = "PUT" | |
urlRequest.httpBody = try? JSONEncoder().encode(object) | |
let task = URLSession.shared.dataTask(with: urlRequest) {(data, response, error) in | |
if let error = error { | |
then(nil, error) | |
return | |
} | |
then(nil, nil) | |
} | |
task.resume() | |
} | |
public func createUrlRequest(for url: URL, header: [String: String] = [:]) -> URLRequest { | |
var urlRequest = URLRequest(url: url) | |
header.forEach { (key, value) in | |
urlRequest.setValue(key, forHTTPHeaderField: value) | |
} | |
return urlRequest | |
} | |
} | |
// MARK: - DEBUG | |
extension RestAPI { | |
private func debugLog(action: Action) { | |
guard showLog else { | |
return | |
} | |
switch action { | |
case .create: | |
debugPrint("POST CREATE: \(baseURL)\(path)") | |
case .delete: | |
debugPrint("DELETE REMOVE: \(baseURL)\(path)") | |
case .getList: | |
debugPrint("GET ALL: \(baseURL)\(path)") | |
case .getOne: | |
debugPrint("GET ONE: \(baseURL)\(path)") | |
default: | |
debugPrint("\(baseURL)\(path)") | |
return | |
} | |
} | |
private func debugLog(data: Data? = nil, response: URLResponse? = nil, error: Error? = nil) { | |
guard showLog else { | |
return | |
} | |
if let error = error { | |
debugPrint(error) | |
} | |
if let response = response { | |
debugPrint(response) | |
} | |
if let data = data { | |
let dataString = String(data: data, encoding: String.Encoding.utf8) | |
debugPrint(dataString ?? data) | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment