My app uses background fetching of web data. Once the data is downloaded during a background session, a processing function is called and, when it's all done, a few key values need to be saved. I'm currently using the UserDefaults to store the updated data. When everything has been processed and the latest data stored in the usual way you use the defaults, I attempt run a synchronize:
// This is at the end of function that runs after a background web session download
defaults.set(x, forKey: "whatever") // There are several of these
if defaults.synchronize() { // Attempt to sycnh
self.logSB.error("Defaults failed to synchronize") // This often prints, maybe all the time
}
(The "self.logSB.error" is similar to "print" but employs SwiftyBeaver logging, which can log in the background.)
This synchromization attempt may work sometimes but definitely fails frequently in background sessions. I've read that when the app is in deep background, the UserDefaults (UD) system is unavailable. I don't fully understand what that means, and I need a workaround.
1. Setting up my background fetch session requires URLs and other details that I've stored in the UD. There is no problem getting these details out of the UD during a background session. Does this mean the UDs already in memory when the app went into the background are still available to the app in the background session? Does the statement about unavailability of the UDs in background sessions mean that the UDs in memory are still available but become disconnected from the ones stored on disk?
2. If I change UDs in a background session by using the typical defaults.set, I suppose only the UD copies in memory are affected and the ones on disk do not change. So what happens when the app comes out of the background? Is there an automatic synchronization? Which UDs take precedence, memory or disk?
I know you can persist data by writing it to a file in a background session and then reading that file when the app becomes active. I do that already with the initial web download. Once that download completes (URLSessionDownloadTask, didFinishDownloadingTo location: URL), the data in that file is processed and that's where I'm having this problem. Do I need to write to a file or simply eliminate the synchronization step?
UPDATE: I found a related post over at StackOverflow, question 20269116. It's several years old and I'm not sure it's still valid. https://stackoverflow.com/questions/20269116/nsuserdefaults-losing-its-keys-values-when-phone-is-rebooted-but-not-unlocked
I've also read a lot of Quinn's posts on this, such as
https://forums.developer.apple.com/thread/15685
Maybe I'm too dense to get it, but I don't understand how the UD seem somewhat available but not fully.