|
|
|
|
@ -116,10 +116,6 @@ public class StoredCollection<T: Storable>: RandomAccessCollection, SomeCollecti |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// self.apiCallsCollection = StoredCollection<ApiCall<T>>(synchronized: false, store: store, loadCompletion: { apiCallCollection in |
|
|
|
|
// self._rescheduleApiCalls() |
|
|
|
|
// }) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
self._load() |
|
|
|
|
@ -131,21 +127,21 @@ public class StoredCollection<T: Storable>: RandomAccessCollection, SomeCollecti |
|
|
|
|
|
|
|
|
|
// MARK: - Paths |
|
|
|
|
|
|
|
|
|
fileprivate func _storageDirectoryPath() throws -> URL { |
|
|
|
|
return try FileUtils.pathForDirectoryInDocuments(directory: Store.storageDirectory) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
fileprivate func _writeToStorageDirectory(content: String, fileName: String) throws { |
|
|
|
|
var fileURL = try self._storageDirectoryPath() |
|
|
|
|
fileURL.append(component: fileName) |
|
|
|
|
try content.write(to: fileURL, atomically: false, encoding: .utf8) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
fileprivate func _urlForJSONFile() throws -> URL { |
|
|
|
|
var storageDirectory = try self._storageDirectoryPath() |
|
|
|
|
storageDirectory.append(component: T.fileName()) |
|
|
|
|
return storageDirectory |
|
|
|
|
} |
|
|
|
|
// fileprivate func _storageDirectoryPath() throws -> URL { |
|
|
|
|
// return try FileUtils.pathForDirectoryInDocuments(directory: Store.storageDirectory) |
|
|
|
|
// } |
|
|
|
|
// |
|
|
|
|
// fileprivate func _writeToStorageDirectory(content: String, fileName: String) throws { |
|
|
|
|
// var fileURL = try self._storageDirectoryPath() |
|
|
|
|
// fileURL.append(component: fileName) |
|
|
|
|
// try content.write(to: fileURL, atomically: false, encoding: .utf8) |
|
|
|
|
// } |
|
|
|
|
// |
|
|
|
|
// fileprivate func _urlForJSONFile() throws -> URL { |
|
|
|
|
// var storageDirectory = try self._storageDirectoryPath() |
|
|
|
|
// storageDirectory.append(component: T.fileName()) |
|
|
|
|
// return storageDirectory |
|
|
|
|
// } |
|
|
|
|
|
|
|
|
|
// MARK: - Loading |
|
|
|
|
|
|
|
|
|
@ -181,7 +177,7 @@ public class StoredCollection<T: Storable>: RandomAccessCollection, SomeCollecti |
|
|
|
|
|
|
|
|
|
/// Decodes the json file into the items array |
|
|
|
|
fileprivate func _decodeJSONFile() throws { |
|
|
|
|
let fileURL = try self._urlForJSONFile() |
|
|
|
|
let fileURL = try T.urlForJSONFile() |
|
|
|
|
|
|
|
|
|
if FileManager.default.fileExists(atPath: fileURL.path()) { |
|
|
|
|
let jsonString: String = try FileUtils.readFile(fileURL: fileURL) |
|
|
|
|
@ -396,8 +392,7 @@ public class StoredCollection<T: Storable>: RandomAccessCollection, SomeCollecti |
|
|
|
|
Logger.log("Start write to \(T.fileName())...") |
|
|
|
|
do { |
|
|
|
|
let jsonString: String = try self.items.jsonString() |
|
|
|
|
try self._writeToStorageDirectory(content: jsonString, fileName: T.fileName()) |
|
|
|
|
// let _ = try FileUtils.writeToDocumentDirectory(content: jsonString, fileName: T.fileName()) |
|
|
|
|
try T.writeToStorageDirectory(content: jsonString, fileName: T.fileName()) |
|
|
|
|
} catch { |
|
|
|
|
Logger.error(error) // TODO how to notify the main project |
|
|
|
|
} |
|
|
|
|
@ -414,7 +409,7 @@ public class StoredCollection<T: Storable>: RandomAccessCollection, SomeCollecti |
|
|
|
|
self.items.removeAll() |
|
|
|
|
|
|
|
|
|
do { |
|
|
|
|
let url: URL = try self._urlForJSONFile() |
|
|
|
|
let url: URL = try T.urlForJSONFile() |
|
|
|
|
if FileManager.default.fileExists(atPath: url.path()) { |
|
|
|
|
try FileManager.default.removeItem(at: url) |
|
|
|
|
} |
|
|
|
|
@ -466,66 +461,16 @@ public class StoredCollection<T: Storable>: RandomAccessCollection, SomeCollecti |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/// Reschedule the api calls if possible |
|
|
|
|
func rescheduleApiCallsIfNecessary() { |
|
|
|
|
Task { |
|
|
|
|
await self.apiCallsCollection?.rescheduleApiCallsIfNecessary() |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// |
|
|
|
|
// /// number of time an execution loop has been called |
|
|
|
|
// fileprivate var _attemptLoops: Int = 0 |
|
|
|
|
// |
|
|
|
|
// /// Indicates if the collection is currently retrying ApiCalls |
|
|
|
|
// fileprivate var _isRetryingCalls: Bool = false |
|
|
|
|
// |
|
|
|
|
// /// Reschedule API calls |
|
|
|
|
// fileprivate func _rescheduleApiCalls() { |
|
|
|
|
// |
|
|
|
|
// guard let apiCallsCollection, apiCallsCollection.isNotEmpty else { |
|
|
|
|
// return |
|
|
|
|
// } |
|
|
|
|
// |
|
|
|
|
// self._isRetryingCalls = true |
|
|
|
|
// self._attemptLoops += 1 |
|
|
|
|
// |
|
|
|
|
// Task { |
|
|
|
|
// |
|
|
|
|
// let delay = pow(2, self._attemptLoops) |
|
|
|
|
// let seconds = NSDecimalNumber(decimal: delay).intValue |
|
|
|
|
// Logger.log("wait for \(seconds) sec") |
|
|
|
|
// try await Task.sleep(until: .now + .seconds(seconds)) |
|
|
|
|
// |
|
|
|
|
// let apiCallsCopy = apiCallsCollection.items |
|
|
|
|
// for apiCall in apiCallsCopy { |
|
|
|
|
// apiCall.attemptsCount += 1 |
|
|
|
|
// apiCall.lastAttemptDate = Date() |
|
|
|
|
// |
|
|
|
|
// do { |
|
|
|
|
// try await self._executeApiCall(apiCall) |
|
|
|
|
//// let _ = try await Store.main.execute(apiCall: apiCall) |
|
|
|
|
// } catch { |
|
|
|
|
// Logger.error(error) |
|
|
|
|
// } |
|
|
|
|
// } |
|
|
|
|
// |
|
|
|
|
// if apiCallsCollection.isEmpty { |
|
|
|
|
// self._isRetryingCalls = false |
|
|
|
|
// } else { |
|
|
|
|
// self._rescheduleApiCalls() |
|
|
|
|
// } |
|
|
|
|
// |
|
|
|
|
// } |
|
|
|
|
// |
|
|
|
|
// } |
|
|
|
|
|
|
|
|
|
/// Returns the content of the API call file as a String |
|
|
|
|
func contentOfApiCallFile() async -> String? { |
|
|
|
|
return await self.apiCallsCollection?.contentOfApiCallFile() |
|
|
|
|
// guard let fileURL = try? self.apiCallsCollection?._urlForJSONFile() else { return nil } |
|
|
|
|
// if FileManager.default.fileExists(atPath: fileURL.path()) { |
|
|
|
|
// return try? FileUtils.readFile(fileURL: fileURL) |
|
|
|
|
// } |
|
|
|
|
// return nil |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/// Returns if the API call collection is not empty |
|
|
|
|
|