|
|
|
|
@ -297,14 +297,14 @@ public class Services { |
|
|
|
|
/// - request: the URLRequest to run |
|
|
|
|
/// - apiCallId: the id of the ApiCall to delete in case of success, or to schedule for a rerun in case of failure |
|
|
|
|
fileprivate func _runSyncPostRequest<T: SyncedStorable>( |
|
|
|
|
_ request: URLRequest, type: T.Type) async throws -> [T] { |
|
|
|
|
_ request: URLRequest, type: T.Type) async throws -> [OperationResult<T>] { |
|
|
|
|
let debugURL = request.url?.absoluteString ?? "" |
|
|
|
|
// print("Run \(request.httpMethod ?? "") \(debugURL)") |
|
|
|
|
let task: (Data, URLResponse) = try await URLSession.shared.data(for: request) |
|
|
|
|
// print("sync POST \(String(describing: T.self)) => \(String(data: task.0, encoding: .utf8) ?? "")") |
|
|
|
|
// print("sync POST \(String(describing: T.self)) => \(String(data: task.0, encoding: .utf8) ?? "")") |
|
|
|
|
|
|
|
|
|
var rescheduleApiCalls: Bool = false |
|
|
|
|
var successes: [T] = [] |
|
|
|
|
var results: [OperationResult<T>] = [] |
|
|
|
|
|
|
|
|
|
if let response = task.1 as? HTTPURLResponse { |
|
|
|
|
let statusCode = response.statusCode |
|
|
|
|
@ -313,20 +313,24 @@ public class Services { |
|
|
|
|
case 200..<300: // success |
|
|
|
|
|
|
|
|
|
let decoded: BatchResponse<T> = try self._decode(data: task.0) |
|
|
|
|
results = decoded.results |
|
|
|
|
|
|
|
|
|
for result in decoded.results { |
|
|
|
|
|
|
|
|
|
switch result.status { |
|
|
|
|
case 200..<300: |
|
|
|
|
if let data = result.data { |
|
|
|
|
successes.append(data) |
|
|
|
|
} |
|
|
|
|
break |
|
|
|
|
// if let data = result.data { |
|
|
|
|
// successes.append(data) |
|
|
|
|
// } |
|
|
|
|
|
|
|
|
|
try await StoreCenter.main.deleteApiCallById(type: T.self, id: result.apiCallId) |
|
|
|
|
// try await StoreCenter.main.deleteApiCallById(type: T.self, id: result.apiCallId) |
|
|
|
|
default: |
|
|
|
|
if let message = result.message { |
|
|
|
|
print(message) |
|
|
|
|
} |
|
|
|
|
rescheduleApiCalls = true |
|
|
|
|
break |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@ -357,7 +361,7 @@ public class Services { |
|
|
|
|
try? await StoreCenter.main.rescheduleApiCalls(type: T.self) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return successes |
|
|
|
|
return results |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/// Returns the URLRequest for an ApiCall |
|
|
|
|
@ -547,7 +551,7 @@ public class Services { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/// Executes an ApiCall |
|
|
|
|
func runApiCalls<T: SyncedStorable>(_ apiCalls: [ApiCall<T>]) async throws -> [T] { |
|
|
|
|
func runApiCalls<T: SyncedStorable>(_ apiCalls: [ApiCall<T>]) async throws -> [OperationResult<T>] { |
|
|
|
|
let request = try self._syncPostRequest(from: apiCalls) |
|
|
|
|
return try await self._runSyncPostRequest(request, type: T.self) |
|
|
|
|
} |
|
|
|
|
@ -774,21 +778,21 @@ public class Services { |
|
|
|
|
/// Executes a POST request |
|
|
|
|
public func post<T: SyncedStorable>(_ instance: T) async throws -> T? { |
|
|
|
|
let apiCall: ApiCall<T> = ApiCall(method: .post, data: instance) |
|
|
|
|
let results: [T] = try await self.runApiCalls([apiCall]) |
|
|
|
|
return results.first |
|
|
|
|
let results: [OperationResult<T>] = try await self.runApiCalls([apiCall]) |
|
|
|
|
return results.first?.data |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/// Executes a PUT request |
|
|
|
|
public func put<T: SyncedStorable>(_ instance: T) async throws -> T { |
|
|
|
|
public func put<T: SyncedStorable>(_ instance: T) async throws -> T? { |
|
|
|
|
let apiCall: ApiCall<T> = ApiCall(method: .put, data: instance) |
|
|
|
|
let results: [T] = try await self.runApiCalls([apiCall]) |
|
|
|
|
return results.first! |
|
|
|
|
let results: [OperationResult<T>] = try await self.runApiCalls([apiCall]) |
|
|
|
|
return results.first?.data |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public func delete<T: SyncedStorable>(_ instance: T) async throws -> T { |
|
|
|
|
public func delete<T: SyncedStorable>(_ instance: T) async throws -> T? { |
|
|
|
|
let apiCall: ApiCall<T> = ApiCall(method: .delete, data: instance) |
|
|
|
|
let results: [T] = try await self.runApiCalls([apiCall]) |
|
|
|
|
return results.first! |
|
|
|
|
let results: [OperationResult<T>] = try await self.runApiCalls([apiCall]) |
|
|
|
|
return results.first?.data |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/// Returns a POST request for the resource |
|
|
|
|
@ -831,11 +835,11 @@ struct BatchResponse<T: Decodable>: Decodable { |
|
|
|
|
var results: [OperationResult<T>] |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
struct OperationResult<T: Decodable>: Decodable { |
|
|
|
|
public struct OperationResult<T: Decodable>: Decodable { |
|
|
|
|
var apiCallId: String |
|
|
|
|
var status: Int |
|
|
|
|
public var status: Int |
|
|
|
|
var data: T? |
|
|
|
|
var message: String? |
|
|
|
|
public var message: String? |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
struct ErrorMessage { |
|
|
|
|
|