diff --git a/LeStorage/Codables/ApiCall.swift b/LeStorage/Codables/ApiCall.swift index aff67ca..90397cc 100644 --- a/LeStorage/Codables/ApiCall.swift +++ b/LeStorage/Codables/ApiCall.swift @@ -21,10 +21,10 @@ class ApiCall: ModelObject, Storable, SomeCall { var id: String = Store.randomId() /// The http URL of the call - var url: String +// var url: String /// The HTTP method of the call: post... - var method: String + var method: HTTPMethod /// The id of the underlying data var dataId: String @@ -38,8 +38,8 @@ class ApiCall: ModelObject, Storable, SomeCall { /// The date of the last execution var lastAttemptDate: Date = Date() - init(url: String, method: String, dataId: String, body: String) { - self.url = url + init(method: HTTPMethod, dataId: String, body: String) { +// self.url = url self.method = method self.dataId = dataId self.body = body diff --git a/LeStorage/Services.swift b/LeStorage/Services.swift index 29869cf..8edfd51 100644 --- a/LeStorage/Services.swift +++ b/LeStorage/Services.swift @@ -7,7 +7,7 @@ import Foundation -public enum HTTPMethod: String, CaseIterable { +public enum HTTPMethod: String, CaseIterable, Codable { case get = "GET" case post = "POST" case put = "PUT" @@ -19,7 +19,7 @@ public enum ServiceError: Error { case cantConvertToUUID(id: String) case missingUserName case responseError(response: String) - case missingToken +// case missingToken } fileprivate enum ServiceConf: String { @@ -59,6 +59,7 @@ public class Services { public init(url: String) { self.baseURL = url self.keychainStore = KeychainStore(serverId: url) + Logger.log("create keystore with id: \(url)") } fileprivate(set) var baseURL: String @@ -163,13 +164,8 @@ public class Services { request.httpMethod = method.rawValue request.setValue("application/json", forHTTPHeaderField: "Content-Type") if !(requiresToken == false) { -// Logger.log("current token = \(token)") - do { - let token = try self.keychainStore.getToken() - request.addValue("Token \(token)", forHTTPHeaderField: "Authorization") - } catch { - throw ServiceError.missingToken - } + let token = try self.keychainStore.getToken() + request.addValue("Token \(token)", forHTTPHeaderField: "Authorization") } return request @@ -200,15 +196,13 @@ public class Services { } fileprivate func _request(from apiCall: ApiCall) throws -> URLRequest { - guard let url = URL(string: apiCall.url) else { - throw ServiceError.urlCreationError(url: apiCall.url) - } + let url = try self._url(from: apiCall) var request = URLRequest(url: url) - request.httpMethod = apiCall.method + request.httpMethod = apiCall.method.rawValue request.httpBody = apiCall.body.data(using: .utf8) request.setValue("application/json", forHTTPHeaderField: "Content-Type") - if let method = HTTPMethod(rawValue: apiCall.method), self._isTokenRequired(type: T.self, method: method) { + if self._isTokenRequired(type: T.self, method: apiCall.method) { do { let token = try self.keychainStore.getToken() request.setValue("Token \(token)", forHTTPHeaderField: "Authorization") @@ -220,6 +214,21 @@ public class Services { return request } + fileprivate func _url(from apiCall: ApiCall) throws -> URL { + var stringURL: String = self.baseURL + switch apiCall.method { + case HTTPMethod.put, HTTPMethod.delete: + stringURL += T.path(id: apiCall.dataId) + default: + stringURL += T.path() + } + if let url = URL(string: stringURL) { + return url + } else { + throw ServiceError.urlCreationError(url: stringURL) + } + } + // MARK: - Authentication public func createAccount(user: U) async throws -> V { @@ -286,7 +295,6 @@ public class Services { try self.keychainStore.deleteToken() } - fileprivate func errorMessageFromResponse(data: Data) -> String? { do { if let jsonObject = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any], let stringsArray = jsonObject.values.first as? [String] { diff --git a/LeStorage/StoredCollection.swift b/LeStorage/StoredCollection.swift index b95759d..27cb198 100644 --- a/LeStorage/StoredCollection.swift +++ b/LeStorage/StoredCollection.swift @@ -412,7 +412,7 @@ public class StoredCollection: RandomAccessCollection, SomeCollecti switch method { case .delete: try self.deleteApiCallById(existingCall.id) // delete the existing call as we don't need it - if existingCall.method == HTTPMethod.post.rawValue { + if existingCall.method == HTTPMethod.post { return nil // if the post has not been done, we can just stop here } else { return try self._createCall(instance, method: method) // otherwise it's a put and we want to send the delete @@ -430,16 +430,7 @@ public class StoredCollection: RandomAccessCollection, SomeCollecti fileprivate func _createCall(_ instance: T, method: HTTPMethod) throws -> ApiCall { let baseURL = try _store.service().baseURL let jsonString = try instance.jsonString() - - let url: String - switch method { - case .get, .post: - url = baseURL + T.path() - case .put, .delete: - url = baseURL + T.path(id: instance.stringId) - } - - return ApiCall(url: url, method: method.rawValue, dataId: String(instance.id), body: jsonString) + return ApiCall(method: method, dataId: String(instance.id), body: jsonString) } /// Prepares a call for execution by updating its properties and adding it to its collection for storage