diff --git a/CHDataManagement/Model/Content.swift b/CHDataManagement/Model/Content.swift index d900974..4f769c7 100644 --- a/CHDataManagement/Model/Content.swift +++ b/CHDataManagement/Model/Content.swift @@ -47,6 +47,9 @@ final class Content: ObservableObject { var errorCallback: ((StorageError) -> Void)? + /// A cache of file sizes + private var fileSizes: [String: Int] = [:] + init() { let settings = Settings.default self.settings = settings @@ -196,4 +199,26 @@ final class Content: ObservableObject { func setLastSaveTimestamp() { self.lastSave = .now } + + // MARK: File sizes + + func size(of file: String) -> Int? { + fileSizes[file] + } + + func cache(size: Int?, of file: String) { + fileSizes[file] = size + } + + // MARK: Image dimensions + + private var imageDimensions: [String: CGSize] = [:] + + func dimensions(of image: String) -> CGSize? { + imageDimensions[image] + } + + func cache(dimensions: CGSize?, of image: String) { + imageDimensions[image] = dimensions + } } diff --git a/CHDataManagement/Model/FileResource.swift b/CHDataManagement/Model/FileResource.swift index 773f47b..4b48dbb 100644 --- a/CHDataManagement/Model/FileResource.swift +++ b/CHDataManagement/Model/FileResource.swift @@ -48,12 +48,22 @@ final class FileResource: Item, LocalizedItem { var isAsset: Bool /// The dimensions of the image - @Published - var imageDimensions: CGSize? = nil + var imageDimensions: CGSize? { + get { content.dimensions(of: id) } + set { + content.cache(dimensions: newValue, of: id) + didChange(save: false) + } + } /// The size of the file in bytes - @Published - var fileSize: Int? = nil + var fileSize: Int? { + get { content.size(of: id) } + set { + content.cache(size: newValue, of: id) + didChange(save: false) + } + } var savedData: Data? diff --git a/CHDataManagement/Model/Item/ChangeObservingItem.swift b/CHDataManagement/Model/Item/ChangeObservingItem.swift index b15f416..5c77199 100644 --- a/CHDataManagement/Model/Item/ChangeObservingItem.swift +++ b/CHDataManagement/Model/Item/ChangeObservingItem.swift @@ -8,7 +8,9 @@ class ChangeObservingItem: ObservableContentItem { /// A dummy property to force views to update when properties change @Published private var changeToggle = false - + + private var shouldSave = true + var cancellables = Set() init(content: Content) { @@ -19,9 +21,18 @@ class ChangeObservingItem: ObservableContentItem { // MARK: Change observation - func didChange() { + func didChange(save: Bool = true) { DispatchQueue.main.async { + self.shouldSave = save self.changeToggle.toggle() + self.shouldSave = true } } + + func needsSaving() { + guard shouldSave else { + return + } + content.needsSave() + } } diff --git a/CHDataManagement/Storage/ChangeObservableItem.swift b/CHDataManagement/Storage/ChangeObservableItem.swift index 67095e6..dba7fd5 100644 --- a/CHDataManagement/Storage/ChangeObservableItem.swift +++ b/CHDataManagement/Storage/ChangeObservableItem.swift @@ -7,6 +7,17 @@ protocol ChangeObservableItem: ObservableObject { func needsSaving() } +extension ChangeObservableItem { + + func observeChanges() { + objectWillChange + .sink { [weak self] _ in + self?.needsSaving() + } + .store(in: &cancellables) + } +} + protocol ObservableContentItem: ChangeObservableItem { var content: Content { get } @@ -18,14 +29,3 @@ extension ObservableContentItem { content.needsSave() } } - -extension ChangeObservableItem { - - func observeChanges() { - objectWillChange - .sink { [weak self] _ in - self?.needsSaving() - } - .store(in: &cancellables) - } -}