I'm trying to use this Published property wrapper extension for persisting data to UserDefaults. This is how it does persist:
projectedValue
.sink { newValue in
print("In .sink, saving data")
let data = try? JSONEncoder().encode(newValue)
_store.set(data, forKey: key)
}
.store(in: &cancellableSet)
there are two problems here I want to fix: 1) don't want to do persist on every change. 2) app can be background'ed or killed while persisting, which can cause data lost. .debounce
was suggested as a solution:
projectedValue
// slow down event publish to not persist on every changes
// .debounce(for: .seconds(10), scheduler: RunLoop.main)
// is .background here mean the same as beginBackgroundTask()?
.debounce(for: .seconds(10), scheduler: DispatchQueue.main, options: .init(qos: .background))
.sink { newValue in
print("In .sink, saving data")
let data = try? JSONEncoder().encode(newValue)
_store.set(data, forKey: key)
}
.store(in: &cancellableSet)
So I found if I use DispatchQueue.main
, I can pass SchedulerOptions
, qos: .background
. I assume here .backgroun
mean make the execution thread like beginBackgroundTask()
? If it's, then it solve both of my problems. But then there is a new problem of app getting background'ed/killed while .debounce()
has pending event before dueTime
is up yet.
Is there anyway to force the debounce
publisher publish any pending event and not wait?
If this is possible, then I can force this to happen in SwiftUI.App.body
when .scenePhase
change to .background
. Right now I’m duplicating the persist logic and running it there.