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 @@ ...@@ -6,14 +6,23 @@
// //
import Foundation import Foundation
import UIKit
/// A decorator Storage that adds delay before saving to the nested storage. /// A decorator Storage that adds delay before saving to the nested storage.
public class DelayedSaveStorage: Storage { public class DelayedSaveStorage: Storage {
private let delay: TimeInterval private let delay: TimeInterval
private let storage: Storage private let storage: Storage
private let savingQueue: OperationQueue = { private let log = Logger(componentName: "DelayedSaveStorage 💾")
private let saveDelayQueue: OperationQueue = {
let queue = 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 queue.maxConcurrentOperationCount = 1
return queue return queue
}() }()
...@@ -30,13 +39,19 @@ public class DelayedSaveStorage: Storage { ...@@ -30,13 +39,19 @@ public class DelayedSaveStorage: Storage {
public init(storage: Storage, delay: TimeInterval) { public init(storage: Storage, delay: TimeInterval) {
self.delay = delay self.delay = delay
self.storage = storage 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?) { public func save(locations: [Location], selectedIndex: Int?) {
latestKnownAppDataSynchronizationQueue.addOperation { latestKnownAppDataSynchronizationQueue.addOperation { [weak self] in
self.latestKnownAppData = AppData(selectedIndex: selectedIndex, locations: locations) self?.latestKnownAppData = AppData(selectedIndex: selectedIndex, locations: locations)
} }
savingQueue.cancelAllOperations() saveDelayQueue.cancelAllOperations()
let saveOperation = BlockOperation() let saveOperation = BlockOperation()
saveOperation.addExecutionBlock { [weak saveOperation, weak self] in saveOperation.addExecutionBlock { [weak saveOperation, weak self] in
guard saveOperation?.isCancelled == false else { guard saveOperation?.isCancelled == false else {
...@@ -48,9 +63,13 @@ public class DelayedSaveStorage: Storage { ...@@ -48,9 +63,13 @@ public class DelayedSaveStorage: Storage {
guard saveOperation?.isCancelled == false else { guard saveOperation?.isCancelled == false else {
return return
} }
self?.storage.save(locations: locations, selectedIndex: selectedIndex) 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) { public func load(completion: @escaping StorageCompletion) {
...@@ -64,4 +83,21 @@ public class DelayedSaveStorage: Storage { ...@@ -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