Commit e0ecac46 by Demid Merzlyakov

IOS-96: bugfix: force immediate save in DelayedSaveStorage, when the app…

IOS-96: bugfix: force immediate save in DelayedSaveStorage, when the app transitions to the background.
parent 37a45923
......@@ -6,14 +6,23 @@
//
import Foundation
import UIKit
/// A decorator Storage that adds delay before saving to the nested storage.
public class DelayedSaveStorage: Storage {
private let delay: TimeInterval
private let storage: Storage
private let savingQueue: OperationQueue = {
private let log = Logger(componentName: "DelayedSaveStorage 💾")
private let saveDelayQueue: OperationQueue = {
let queue = OperationQueue()
queue.name = "DelayedSaveStorageSavingQueue"
queue.name = "DelayedSaveStorageSaveDelayQueue"
queue.maxConcurrentOperationCount = 1
return queue
}()
private let saveQueue: OperationQueue = {
let queue = OperationQueue()
queue.name = "DelayedSaveStorageSaveQueue"
queue.maxConcurrentOperationCount = 1
return queue
}()
......@@ -30,13 +39,19 @@ public class DelayedSaveStorage: Storage {
public init(storage: Storage, delay: TimeInterval) {
self.delay = delay
self.storage = storage
NotificationCenter.default.addObserver(self, selector: #selector(handleSwitchToBackground), name: UIApplication.didEnterBackgroundNotification, object: nil)
}
deinit {
NotificationCenter.default.removeObserver(self)
}
public func save(locations: [Location], selectedIndex: Int?) {
latestKnownAppDataSynchronizationQueue.addOperation {
self.latestKnownAppData = AppData(selectedIndex: selectedIndex, locations: locations)
latestKnownAppDataSynchronizationQueue.addOperation { [weak self] in
self?.latestKnownAppData = AppData(selectedIndex: selectedIndex, locations: locations)
}
savingQueue.cancelAllOperations()
saveDelayQueue.cancelAllOperations()
let saveOperation = BlockOperation()
saveOperation.addExecutionBlock { [weak saveOperation, weak self] in
guard saveOperation?.isCancelled == false else {
......@@ -48,9 +63,13 @@ public class DelayedSaveStorage: Storage {
guard saveOperation?.isCancelled == false else {
return
}
self?.saveQueue.addOperation {
if saveOperation?.isCancelled != true {
self?.storage.save(locations: locations, selectedIndex: selectedIndex)
}
savingQueue.addOperation(saveOperation)
}
}
saveDelayQueue.addOperation(saveOperation)
}
public func load(completion: @escaping StorageCompletion) {
......@@ -64,4 +83,21 @@ public class DelayedSaveStorage: Storage {
}
}
}
@objc
private func handleSwitchToBackground() {
saveDelayQueue.cancelAllOperations()
self.saveQueue.addOperation { [weak self] in
self?.latestKnownAppDataSynchronizationQueue.addOperation {
guard let self = self else { return }
guard let appData = self.latestKnownAppData else {
return
}
self.log.debug("Switch to background: force save")
self.storage.save(locations: appData.locations, selectedIndex: appData.selectedIndex)
}
self?.latestKnownAppDataSynchronizationQueue.waitUntilAllOperationsAreFinished()
}
self.saveQueue.waitUntilAllOperationsAreFinished()
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment