Skip to content

Instantly share code, notes, and snippets.

@RxDx
Created May 3, 2018 22:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save RxDx/1819bae2e6da2c11f74815d313943daf to your computer and use it in GitHub Desktop.
Save RxDx/1819bae2e6da2c11f74815d313943daf to your computer and use it in GitHub Desktop.
//
// 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