From cd0d5bf1ff577cefe8c4d6a9b486b56524e16e37 Mon Sep 17 00:00:00 2001 From: Laurent Date: Mon, 22 Apr 2024 17:12:13 +0200 Subject: [PATCH] fix conflict --- LeStorage/Codables/Settings.swift | 2 +- LeStorage/MicroStorage.swift | 3 +-- LeStorage/Services.swift | 12 ++++++++++-- LeStorage/Store.swift | 19 ++++++++++++------- LeStorage/StoredCollection.swift | 14 +++++++++----- LeStorage/Utils/Codable+Extensions.swift | 16 +++++++++------- 6 files changed, 42 insertions(+), 24 deletions(-) diff --git a/LeStorage/Codables/Settings.swift b/LeStorage/Codables/Settings.swift index c64e7d0..34d04aa 100644 --- a/LeStorage/Codables/Settings.swift +++ b/LeStorage/Codables/Settings.swift @@ -17,6 +17,6 @@ class Settings: MicroStorable { // var id: String = Store.randomId() - var userUUIDString: String? = nil + var userId: String? = nil var username: String? = nil } diff --git a/LeStorage/MicroStorage.swift b/LeStorage/MicroStorage.swift index 458c1e7..b6b9958 100644 --- a/LeStorage/MicroStorage.swift +++ b/LeStorage/MicroStorage.swift @@ -20,8 +20,7 @@ public class MicroStorage { var instance: T? = nil do { let url = try FileUtils.pathForFileInDocumentDirectory(T.fileName) - let fileExists = FileManager.default.fileExists(atPath: url.path()) - if fileExists { + if FileManager.default.fileExists(atPath: url.path()) { let jsonString = try FileUtils.readDocumentFile(fileName: T.fileName) if let decoded: T = try jsonString.decode() { instance = decoded diff --git a/LeStorage/Services.swift b/LeStorage/Services.swift index 9eafd25..5ffbbf2 100644 --- a/LeStorage/Services.swift +++ b/LeStorage/Services.swift @@ -14,7 +14,7 @@ enum Method: String { case delete = "DELETE" } -enum ServiceError: Error { +public enum ServiceError: Error { case urlCreationError(url: String) case cantConvertToUUID(id: String) case missingUserName @@ -113,7 +113,12 @@ public class Services { try Store.main.rescheduleApiCall(id: apiCallId, type: type) } Logger.log("Failed Run \(request.httpMethod ?? "") \(request.url?.absoluteString ?? "")") - let dataString = String(describing: String(data: task.0, encoding: .utf8)) + var dataString = String(describing: String(data: task.0, encoding: .utf8)) + if let nfe: NonFieldError = try? JSONDecoder().decode(NonFieldError.self, from: task.0) { + if let reason = nfe.non_field_errors.first { + dataString = reason + } + } throw ServiceError.responseError(response: dataString) } } @@ -284,6 +289,9 @@ struct Token: Codable { struct Email: Codable { var email: String } +struct NonFieldError: Codable { + var non_field_errors: [String] +} public protocol UserBase: Codable { var id: String { get } diff --git a/LeStorage/Store.swift b/LeStorage/Store.swift index 71aa40b..f9becb8 100644 --- a/LeStorage/Store.swift +++ b/LeStorage/Store.swift @@ -72,10 +72,10 @@ public class Store { /// Registers a collection /// [synchronize] denotes a collection which modification will be sent to the django server - public func registerCollection(synchronized: Bool, indexed: Bool = false, inMemory: Bool = false) -> StoredCollection { + public func registerCollection(synchronized: Bool, indexed: Bool = false, inMemory: Bool = false, sendsUpdate: Bool = true) -> StoredCollection { // register collection - let collection = StoredCollection(synchronized: synchronized, store: Store.main, indexed: indexed, inMemory: inMemory, loadCompletion: nil) + let collection = StoredCollection(synchronized: synchronized, store: Store.main, indexed: indexed, inMemory: inMemory, sendsUpdate: sendsUpdate, loadCompletion: nil) self._collections[T.resourceName()] = collection // if synchronized { // register additional collection for api calls @@ -92,18 +92,18 @@ public class Store { func setUserUUID(uuidString: String) { self.settingsStorage.update { settings in - settings.userUUIDString = uuidString + settings.userId = uuidString } } public func currentUserUUID() -> UUID { - if let uuidString = self.settingsStorage.item.userUUIDString, + if let uuidString = self.settingsStorage.item.userId, let uuid = UUID(uuidString: uuidString) { return uuid } else { let uuid = UIDevice.current.identifierForVendor ?? UUID() self.settingsStorage.update { settings in - settings.userUUIDString = uuid.uuidString + settings.userId = uuid.uuidString } return uuid } @@ -114,12 +114,17 @@ public class Store { } func setUserName(_ username: String) { - self.settingsStorage.item.username = username + self.settingsStorage.update { settings in + settings.username = username + } } public func disconnect() { try? self.service().disconnect() - self.settingsStorage.item.userUUIDString = nil + self.settingsStorage.update { settings in + settings.username = nil + settings.userId = nil + } } public func hasToken() -> Bool { diff --git a/LeStorage/StoredCollection.swift b/LeStorage/StoredCollection.swift index 8dfa3df..bc1e8c1 100644 --- a/LeStorage/StoredCollection.swift +++ b/LeStorage/StoredCollection.swift @@ -33,6 +33,9 @@ public class StoredCollection: RandomAccessCollection, SomeCollecti /// Doesn't write the collection in a file fileprivate var _inMemory: Bool = false + /// Indicates if the synchronized collection sends update to the API + fileprivate var _sendsUpdate: Bool = true + /// The list of stored items @Published public fileprivate(set) var items: [T] = [] @@ -66,13 +69,14 @@ public class StoredCollection: RandomAccessCollection, SomeCollecti /// Denotes a collection that loads and writes asynchronousIO fileprivate var asynchronousIO: Bool = true - init(synchronized: Bool, store: Store, indexed: Bool = false, asynchronousIO: Bool = true, inMemory: Bool = false, loadCompletion: ((StoredCollection) -> ())? = nil) { + init(synchronized: Bool, store: Store, indexed: Bool = false, asynchronousIO: Bool = true, inMemory: Bool = false, sendsUpdate: Bool = true, loadCompletion: ((StoredCollection) -> ())? = nil) { self.synchronized = synchronized self.asynchronousIO = asynchronousIO if indexed { self._index = [:] } self._inMemory = inMemory + self._sendsUpdate = sendsUpdate self._store = store self.loadCompletion = loadCompletion @@ -103,7 +107,7 @@ public class StoredCollection: RandomAccessCollection, SomeCollecti } fileprivate func _loadFromFile() throws { - let url = try FileUtils.pathForFileInDocumentDirectory(T.fileName()) + let url: URL = try FileUtils.pathForFileInDocumentDirectory(T.fileName()) if FileManager.default.fileExists(atPath: url.path()) { if self.asynchronousIO { @@ -120,7 +124,7 @@ public class StoredCollection: RandomAccessCollection, SomeCollecti /// Decodes the json file into the items array fileprivate func _decodeJSONFile() throws { - let jsonString = try FileUtils.readDocumentFile(fileName: T.fileName()) + let jsonString: String = try FileUtils.readDocumentFile(fileName: T.fileName()) if let decoded: [T] = try jsonString.decodeArray() { DispatchQueue.main.async { Logger.log("loaded \(T.fileName()) with \(decoded.count) items") @@ -353,7 +357,7 @@ public class StoredCollection: RandomAccessCollection, SomeCollecti /// Sends an update api call for the provided [instance] fileprivate func _sendUpdateIfNecessary(_ instance: T) throws { - guard self.synchronized else { + guard self.synchronized, self._sendsUpdate else { return } @@ -408,7 +412,7 @@ public class StoredCollection: RandomAccessCollection, SomeCollecti } fileprivate func _rescheduleApiCalls() { - return +// return guard let apiCallsCollection, apiCallsCollection.isNotEmpty else { return diff --git a/LeStorage/Utils/Codable+Extensions.swift b/LeStorage/Utils/Codable+Extensions.swift index ddaacb4..5bd1c8d 100644 --- a/LeStorage/Utils/Codable+Extensions.swift +++ b/LeStorage/Utils/Codable+Extensions.swift @@ -10,7 +10,9 @@ import Foundation fileprivate var jsonEncoder: JSONEncoder = { let encoder = JSONEncoder() encoder.keyEncodingStrategy = .convertToSnakeCase + #if DEBUG encoder.outputFormatting = .prettyPrinted + #endif encoder.dateEncodingStrategy = .iso8601 return encoder }() @@ -24,16 +26,16 @@ fileprivate var jsonDecoder: JSONDecoder = { extension Encodable { - func jsonString() throws -> String { + public func jsonString() throws -> String { let data = try self.jsonData() return String(data: data, encoding: .utf8) ?? "" } - func jsonData() throws -> Data { + public func jsonData() throws -> Data { return try jsonEncoder.encode(self) } - func prettyJSONString() throws -> String { + public func prettyJSONString() throws -> String { let data = try jsonEncoder.encode(self) return String(data: data, encoding: .utf8) ?? "" } @@ -42,11 +44,11 @@ extension Encodable { extension String { - func decode() throws -> T? { + public func decode() throws -> T? { return try self.data(using: .utf8)?.decode() } - func decodeArray() throws -> [T]? { + public func decodeArray() throws -> [T]? { return try self.data(using: .utf8)?.decodeArray() } @@ -54,11 +56,11 @@ extension String { extension Data { - func decode() throws -> T { + public func decode() throws -> T { return try jsonDecoder.decode(T.self, from: self) } - func decodeArray() throws -> [T] { + public func decodeArray() throws -> [T] { return try jsonDecoder.decode([T].self, from: self) }