AutoCat2/Shared/Utils/Api.swift
2021-07-07 20:10:13 +03:00

106 lines
4.6 KiB
Swift

import Foundation
public class Api {
private var session: URLSession
public static let shared = Api()
public init(session: URLSession? = nil) {
if let session = session {
self.session = session
} else {
let sessionConfig = URLSessionConfiguration.default
sessionConfig.timeoutIntervalForRequest = 60.0
sessionConfig.timeoutIntervalForResource = 60.0
self.session = URLSession(configuration: sessionConfig)
}
}
// MARK: - Private wrappres
private func genError(_ msg: String, suggestion: String, code: Int = 0) -> Error {
return NSError(domain: "", code: code, userInfo: [NSLocalizedDescriptionKey: msg, NSLocalizedRecoverySuggestionErrorKey: suggestion])
}
private func createRequest<B,P>(api: String, method: String, body: B? = nil, params: [String:P]? = nil) -> URLRequest? where B: Encodable, P: LosslessStringConvertible {
guard var urlComponents = URLComponents(string: Constants.baseUrl + api) else { return nil }
if let params = params, method.uppercased() == "GET" {
urlComponents.queryItems = params.map { URLQueryItem(name: $0, value: String($1)) }
}
var request = URLRequest(url: urlComponents.url!)
request.httpMethod = method
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("application/json", forHTTPHeaderField: "Accept")
request.addValue("Bearer " + Settings.shared.user.token, forHTTPHeaderField: "Authorization")
if let body = body, method.uppercased() != "GET" {
let encoder = JSONEncoder()
encoder.outputFormatting = .prettyPrinted
if let data = try? encoder.encode(body) {
request.httpBody = data
}
}
return request
}
private func makeRequest<T,B,P>(api: String, method: String = "GET", body: B?, params: [String:P]? = nil) async throws -> T where T: Decodable, B: Encodable, P: LosslessStringConvertible {
guard let request = self.createRequest(api: api, method: method, body: body, params: params) else {
throw self.genError("Error creating request", suggestion: "")
}
let (data, response) = try await self.session.data(for: request)
// let str = String(data: data, encoding: .utf8)
// print("================================")
// if let string = str?.replacingOccurrences(of: "\\\"", with: "\"")
// .replacingOccurrences(of: "\\'", with: "'")
// .replacingOccurrences(of: "\\n", with: "") {
// print(string)
// }
// print("================================")
do {
let resp = try JSONDecoder().decode(Response<T>.self, from: data)
if resp.success {
return resp.data!
} else {
throw self.genError(resp.error!, suggestion: "")
}
} catch let error as Swift.DecodingError {
throw CocoaError.error((error as CustomDebugStringConvertible).debugDescription)
} catch {
throw error
}
}
private func makeGetRequest<T,P>(api: String, params:[String: P]? = nil) async throws -> T where T: Decodable, P: LosslessStringConvertible {
return try await self.makeRequest(api: api, method: "GET", body: nil as Int?, params: params)
}
private func makeEmptyGetRequest<T>(api: String) async throws -> T where T: Decodable {
return try await self.makeRequest(api: api, method: "GET", body: nil as Int?, params: nil as [String:Int]?)
}
private func makeEmptyBodyRequest<T>(api: String, method: String = "POST") async throws -> T where T: Decodable {
return try await self.makeRequest(api: api, method: method, body: nil as Int?, params: nil as [String:Int]?)
}
private func makeBodyRequest<T,B>(api: String, body: B?, method: String = "POST") async throws -> T where T: Decodable, B: Encodable {
return try await self.makeRequest(api: api, method: method, body: body, params: nil as [String:Int]?)
}
// MARK: - AutoCat public API
public static func login(email: String, password: String) async throws -> User {
let body = [
"email": email,
"password": password
]
return try await self.shared.makeBodyRequest(api: "user/login", body: body)
}
}