Adding API wrapper
This commit is contained in:
parent
943a3635fb
commit
ab2b7e15fa
@ -32,6 +32,10 @@
|
|||||||
7A40D5FF2693A91F009B0BC4 /* CocoaError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A40D5FD2693A91F009B0BC4 /* CocoaError.swift */; };
|
7A40D5FF2693A91F009B0BC4 /* CocoaError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A40D5FD2693A91F009B0BC4 /* CocoaError.swift */; };
|
||||||
7A40D6022694FF5D009B0BC4 /* Api.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A40D6012694FF5D009B0BC4 /* Api.swift */; };
|
7A40D6022694FF5D009B0BC4 /* Api.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A40D6012694FF5D009B0BC4 /* Api.swift */; };
|
||||||
7A40D6032694FF5D009B0BC4 /* Api.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A40D6012694FF5D009B0BC4 /* Api.swift */; };
|
7A40D6032694FF5D009B0BC4 /* Api.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A40D6012694FF5D009B0BC4 /* Api.swift */; };
|
||||||
|
7A683999269612EA00B2188A /* Response.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A683998269612EA00B2188A /* Response.swift */; };
|
||||||
|
7A68399A269612EA00B2188A /* Response.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A683998269612EA00B2188A /* Response.swift */; };
|
||||||
|
7ACD05D72695C08A00557667 /* Constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7ACD05D62695C08A00557667 /* Constants.swift */; };
|
||||||
|
7ACD05D82695C08A00557667 /* Constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7ACD05D62695C08A00557667 /* Constants.swift */; };
|
||||||
/* End PBXBuildFile section */
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
/* Begin PBXContainerItemProxy section */
|
/* Begin PBXContainerItemProxy section */
|
||||||
@ -101,6 +105,8 @@
|
|||||||
7A40D5F52693A63A009B0BC4 /* SettingsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsTests.swift; sourceTree = "<group>"; };
|
7A40D5F52693A63A009B0BC4 /* SettingsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsTests.swift; sourceTree = "<group>"; };
|
||||||
7A40D5FD2693A91F009B0BC4 /* CocoaError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CocoaError.swift; sourceTree = "<group>"; };
|
7A40D5FD2693A91F009B0BC4 /* CocoaError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CocoaError.swift; sourceTree = "<group>"; };
|
||||||
7A40D6012694FF5D009B0BC4 /* Api.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Api.swift; sourceTree = "<group>"; };
|
7A40D6012694FF5D009B0BC4 /* Api.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Api.swift; sourceTree = "<group>"; };
|
||||||
|
7A683998269612EA00B2188A /* Response.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Response.swift; sourceTree = "<group>"; };
|
||||||
|
7ACD05D62695C08A00557667 /* Constants.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Constants.swift; sourceTree = "<group>"; };
|
||||||
/* End PBXFileReference section */
|
/* End PBXFileReference section */
|
||||||
|
|
||||||
/* Begin PBXFrameworksBuildPhase section */
|
/* Begin PBXFrameworksBuildPhase section */
|
||||||
@ -212,6 +218,7 @@
|
|||||||
children = (
|
children = (
|
||||||
7A40D5E026924AEC009B0BC4 /* User.swift */,
|
7A40D5E026924AEC009B0BC4 /* User.swift */,
|
||||||
7A40D5E226924B09009B0BC4 /* Settings.swift */,
|
7A40D5E226924B09009B0BC4 /* Settings.swift */,
|
||||||
|
7A683998269612EA00B2188A /* Response.swift */,
|
||||||
);
|
);
|
||||||
path = Models;
|
path = Models;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -259,6 +266,7 @@
|
|||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
7A40D6012694FF5D009B0BC4 /* Api.swift */,
|
7A40D6012694FF5D009B0BC4 /* Api.swift */,
|
||||||
|
7ACD05D62695C08A00557667 /* Constants.swift */,
|
||||||
);
|
);
|
||||||
path = Utils;
|
path = Utils;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -454,8 +462,10 @@
|
|||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
7A40D5E926938BEC009B0BC4 /* AuthView.swift in Sources */,
|
7A40D5E926938BEC009B0BC4 /* AuthView.swift in Sources */,
|
||||||
|
7ACD05D72695C08A00557667 /* Constants.swift in Sources */,
|
||||||
7A40D5E326924B09009B0BC4 /* Settings.swift in Sources */,
|
7A40D5E326924B09009B0BC4 /* Settings.swift in Sources */,
|
||||||
7A40D5A02691C6D8009B0BC4 /* AutoCat2App.swift in Sources */,
|
7A40D5A02691C6D8009B0BC4 /* AutoCat2App.swift in Sources */,
|
||||||
|
7A683999269612EA00B2188A /* Response.swift in Sources */,
|
||||||
7A40D5A42691C6D8009B0BC4 /* Persistence.swift in Sources */,
|
7A40D5A42691C6D8009B0BC4 /* Persistence.swift in Sources */,
|
||||||
7A40D5ED2693A1EA009B0BC4 /* AuthVM.swift in Sources */,
|
7A40D5ED2693A1EA009B0BC4 /* AuthVM.swift in Sources */,
|
||||||
7A40D59E2691C6D8009B0BC4 /* AutoCat2.xcdatamodeld in Sources */,
|
7A40D59E2691C6D8009B0BC4 /* AutoCat2.xcdatamodeld in Sources */,
|
||||||
@ -471,8 +481,10 @@
|
|||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
7A40D5EA26938BEC009B0BC4 /* AuthView.swift in Sources */,
|
7A40D5EA26938BEC009B0BC4 /* AuthView.swift in Sources */,
|
||||||
|
7ACD05D82695C08A00557667 /* Constants.swift in Sources */,
|
||||||
7A40D5A12691C6D8009B0BC4 /* AutoCat2App.swift in Sources */,
|
7A40D5A12691C6D8009B0BC4 /* AutoCat2App.swift in Sources */,
|
||||||
7A40D5A52691C6D8009B0BC4 /* Persistence.swift in Sources */,
|
7A40D5A52691C6D8009B0BC4 /* Persistence.swift in Sources */,
|
||||||
|
7A68399A269612EA00B2188A /* Response.swift in Sources */,
|
||||||
7A40D5E526924B0C009B0BC4 /* User.swift in Sources */,
|
7A40D5E526924B0C009B0BC4 /* User.swift in Sources */,
|
||||||
7A40D5EE2693A1EA009B0BC4 /* AuthVM.swift in Sources */,
|
7A40D5EE2693A1EA009B0BC4 /* AuthVM.swift in Sources */,
|
||||||
7A40D59F2691C6D8009B0BC4 /* AutoCat2.xcdatamodeld in Sources */,
|
7A40D59F2691C6D8009B0BC4 /* AutoCat2.xcdatamodeld in Sources */,
|
||||||
|
|||||||
25
Shared/Models/Response.swift
Normal file
25
Shared/Models/Response.swift
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
import Foundation
|
||||||
|
|
||||||
|
class Response<T>: Decodable where T: Decodable {
|
||||||
|
let success: Bool
|
||||||
|
let data: T?
|
||||||
|
let error: String?
|
||||||
|
|
||||||
|
enum CodingKeys: String, CodingKey {
|
||||||
|
case success
|
||||||
|
case data
|
||||||
|
case error
|
||||||
|
}
|
||||||
|
|
||||||
|
required init(from decoder: Decoder) throws {
|
||||||
|
let container = try decoder.container(keyedBy: CodingKeys.self)
|
||||||
|
success = try container.decode(Bool.self, forKey: .success)
|
||||||
|
if success {
|
||||||
|
data = try container.decode(T.self, forKey: .data)
|
||||||
|
error = nil
|
||||||
|
} else {
|
||||||
|
error = try container.decode(String.self, forKey: .error)
|
||||||
|
data = nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,8 +1,105 @@
|
|||||||
//
|
|
||||||
// Api.swift
|
|
||||||
// AutoCat2
|
|
||||||
//
|
|
||||||
// Created by Selim Mustafaev on 07.07.2021.
|
|
||||||
//
|
|
||||||
|
|
||||||
import Foundation
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
13
Shared/Utils/Constants.swift
Normal file
13
Shared/Utils/Constants.swift
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
import Foundation
|
||||||
|
|
||||||
|
public struct Constants {
|
||||||
|
public static var baseUrl: String {
|
||||||
|
#if DEBUG
|
||||||
|
//return "http://127.0.0.1:3000/"
|
||||||
|
//return "http://192.168.1.67:3000/"
|
||||||
|
return "https://vps.aliencat.pro:8443/"
|
||||||
|
#else
|
||||||
|
return "https://vps.aliencat.pro:8443/"
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user