diff --git a/LeStorage/ApiCallCollection.swift b/LeStorage/ApiCallCollection.swift index 6733c06..3026328 100644 --- a/LeStorage/ApiCallCollection.swift +++ b/LeStorage/ApiCallCollection.swift @@ -238,38 +238,40 @@ actor ApiCallCollection: SomeCallCollection { fileprivate func _call(method: HTTPMethod, instance: T? = nil) async throws -> ApiCall? { if let instance { - return try await self._callForInstance(method, instance: instance) + return try await self._callForInstance(instance, method: method) } else { if self.items.contains(where: { $0.method == .get }) { return nil } else { - return try self._createCall(.get) + return try self._createGetCall() } } } - fileprivate func _callForInstance(_ method: HTTPMethod, instance: T) async throws -> ApiCall? { + fileprivate func _callForInstance(_ instance: T, method: HTTPMethod, transactionId: String? = nil) async throws -> ApiCall { + + // cleanup + let existingCalls = self.items.filter { $0.dataId == instance.stringId } + self._deleteCalls(existingCalls) - if let existingCall = self.items.first(where: { $0.dataId == instance.stringId }) { - switch method { - case .delete: - self.deleteById(existingCall.id) // delete the existing call as we don't need it - if existingCall.method == HTTPMethod.post { - return nil // if the post has not been done, we can just stop here - } else { - return try self._createCall(method, instance: instance) // otherwise it's a put and we want to send the delete - } - default: // here we should only trying to PUT, so we update the existing POST/PUT with the instance new values - existingCall.body = try instance.jsonString() - return existingCall - } - } else { - return try self._createCall(method, instance: instance) + // create + let call = try self._createCall(method, instance: instance, transactionId: transactionId) + self._prepareCall(apiCall: call) + return call + } + + fileprivate func _deleteCalls(_ calls: [ApiCall]) { + for call in calls { + self.deleteById(call.id) } } + fileprivate func _createGetCall() throws -> ApiCall { + return try self._createCall(.get, instance: nil) + } + /// Creates an API call for the Storable [instance] and an HTTP [method] - fileprivate func _createCall(_ method: HTTPMethod, instance: T? = nil, transactionId: String? = nil) throws -> ApiCall { + fileprivate func _createCall(_ method: HTTPMethod, instance: T?, transactionId: String? = nil) throws -> ApiCall { if let instance { let jsonString = try instance.jsonString() return ApiCall(method: method, dataId: instance.stringId, body: jsonString, transactionId: transactionId) @@ -302,31 +304,34 @@ actor ApiCallCollection: SomeCallCollection { var apiCalls: [ApiCall] = [] let transactionId = Store.randomId() for insert in batch.inserts { - let call = try self._createCall(.post, instance: insert, transactionId: transactionId) - self._prepareCall(apiCall: call) + let call = try await self._callForInstance(insert, method: .post, transactionId: transactionId) apiCalls.append(call) } for update in batch.updates { - let call = try self._createCall(.put, instance: update, transactionId: transactionId) - self._prepareCall(apiCall: call) + let call = try await self._callForInstance(update, method: .put, transactionId: transactionId) apiCalls.append(call) } for delete in batch.deletes { - let call = try self._createCall(.delete, instance: delete, transactionId: transactionId) - self._prepareCall(apiCall: call) + let call = try await self._callForInstance(delete, method: .delete, transactionId: transactionId) apiCalls.append(call) } return try await self._executeApiCalls(apiCalls) } - /// Initiates the process of sending the data with the server - fileprivate func _sendServerRequest(_ method: HTTPMethod, instance: T? = nil) async throws -> V? { - if let apiCall = try await self._call(method: method, instance: instance) { - return try await self._prepareAndSendCall(apiCall) - } else { - return nil - } - } +// /// Initiates the process of sending the data with the server +//<<<<<<< HEAD +// fileprivate func _sendServerRequest(_ method: HTTPMethod, instance: T? = nil) async throws -> V? { +// if let apiCall = try await self._call(method: method, instance: instance) { +// return try await self._prepareAndSendCall(apiCall) +//======= +// fileprivate func _synchronize(_ instance: T, method: HTTPMethod) async throws -> V? { +// if let apiCall = try await self._callForInstance(instance, method: method) { +// return try await self._executeApiCall(apiCall) +//>>>>>>> main +// } else { +// return nil +// } +// } fileprivate func _prepareAndSendCall(_ apiCall: ApiCall) async throws -> V? { self._prepareCall(apiCall: apiCall) diff --git a/LeStorage/Services.swift b/LeStorage/Services.swift index 7ea78ad..2e5b419 100644 --- a/LeStorage/Services.swift +++ b/LeStorage/Services.swift @@ -331,12 +331,12 @@ public class Services { /// - Parameters: /// - apiCall: An ApiCall instance to configure the returned request fileprivate func _syncGetRequest(from apiCall: ApiCall) throws -> URLRequest { - + var urlString = baseURL + "data/" if let urlParameters = apiCall.formattedURLParameters() { urlString.append(urlParameters) } - + guard let url = URL(string: urlString) else { throw ServiceError.urlCreationError(url: urlString) } @@ -344,14 +344,35 @@ public class Services { var request = URLRequest(url: url) request.httpMethod = HTTPMethod.get.rawValue request.setValue("application/json", forHTTPHeaderField: "Content-Type") - + if self._isTokenRequired(type: T.self, method: apiCall.method) { let token = try self.keychainStore.getValue() request.addValue("Token \(token)", forHTTPHeaderField: "Authorization") } - + return request } +//======= +// +// /// Executes a PUT request +// public func put(_ instance: T) async throws -> T { +// var postRequest = try self._putRequest(type: T.self, id: instance.stringId) +// postRequest.httpBody = try jsonEncoder.encode(instance) +// return try await self._runRequest(postRequest) +// } +// +// public func delete(_ instance: T) async throws -> T { +// let deleteRequest = try self._deleteRequest(type: T.self, id: instance.stringId) +// return try await self._runRequest(deleteRequest) +// } +// +// /// Executes an ApiCall +// func runApiCall(_ apiCall: ApiCall) async throws -> V { +// let request = try self._request(from: apiCall) +// print("HTTP \(request.httpMethod ?? "") : id = \(apiCall.dataId)") +// return try await self._runRequest(request, apiCall: apiCall) +//>>>>>>> main +// } /// Returns the URLRequest for an ApiCall /// - Parameters: