Makes the call creation strategy more resilient

sync2
Laurent 9 months ago
parent 339df068a8
commit 1d333e6f03
  1. 29
      LeStorage/ApiCallCollection.swift
  2. 7
      LeStorage/Services.swift

@ -218,21 +218,19 @@ actor ApiCallCollection<T: Storable>: SomeCallCollection {
/// The method updates existing calls or creates a new one
fileprivate func _callForInstance(_ instance: T, method: HTTPMethod) async throws -> ApiCall<T>? {
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(instance, method: method) // 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(instance, method: method)
// cleanup
let existingCalls = self.items.filter { $0.dataId == instance.stringId }
self._deleteCalls(existingCalls)
// create
let call = try self._createCall(instance, method: method)
self._prepareCall(apiCall: call)
return call
}
fileprivate func _deleteCalls(_ calls: [ApiCall<T>]) {
for call in calls {
self.deleteById(call.id)
}
}
@ -294,7 +292,6 @@ actor ApiCallCollection<T: Storable>: SomeCallCollection {
/// Initiates the process of sending the data with the server
fileprivate func _synchronize<V: Decodable>(_ instance: T, method: HTTPMethod) async throws -> V? {
if let apiCall = try await self._callForInstance(instance, method: method) {
self._prepareCall(apiCall: apiCall)
return try await self._executeApiCall(apiCall)
} else {
return nil

@ -142,7 +142,7 @@ public class Services {
Logger.w(message)
}
if !(V.self is Empty?.Type) {
if !(V.self is Empty?.Type) && !(V.self is Empty.Type) {
return try jsonDecoder.decode(V.self, from: task.0)
} else {
return try jsonDecoder.decode(V.self, from: "{}".data(using: .utf8)!)
@ -280,6 +280,11 @@ public class Services {
return try await self._runRequest(postRequest)
}
public func delete<T: Storable>(_ 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<T: Storable, V: Decodable>(_ apiCall: ApiCall<T>) async throws -> V {
let request = try self._request(from: apiCall)

Loading…
Cancel
Save