Is it possible that the UserDefaults.standard values ​​won't be readable?

I know that UserDefaults are just for storing preferences, but those preferences are persistent - the values ​​stored in UserDefaults are supported across unlimited app launches and are always readable as long as the app stays installed. right?

Is it possible that these values ​​will get cleared or not be properly available at any point? After years of using UserDefaults, and depending on the consistency of the values ​​they store, I now saw twice in one day of work that when my application started and checked a simple boolean, the value was wrong.

if defaults.bool(forKey: "beenLaunched") {

      

This code runs every time the application starts. If true I don't do anything, but if false I set multiple values ​​since this is the first application launch for the user and then I call defaults.set (true, forKey: "wasLaunched") and defaults.set (0 , forKey: "eventsCompleted") and several other values.

I found this thread on the Apple forums in which Eskimo said: "For the central method NSUserDefaults -objectForKey: a nil result means that the value is not available, but there is no way to distinguish this key from it, and this value cannot be selected because user preferences inactive by default. " (This looks like a specific case of background startup when the device is locked )

I can consider a safer way to store simple data like a Bool, Int or String value, but using UserDefaults for these value types has always been simple, straightforward, and reliable. Can anyone ponder this question and if I am wrong to believe in the persistence of UserDefaults?

Thank!

+3


source to share


2 answers


UserDefaults

is not a "service"; it is never available for your application. The file it writes is PLIST (and therefore all values ​​are stored according to the PLIST standard). For example, all numbers (including booleans) are saved as NSNumber

a file and can be retrieved either with object(forKey:)

or bool(forKey:)

. If you use a method on an object and nothing is set for that value, you get nil

whose boolean value is false

(or 0

). It's the same if you use a boolean method (you get false

). This means that no matter which way you go, you will always get false if there is no value or value false

. Create your logic around (which you already have - "beenLaunched"

will be empty and thereforefalse

if it has never been started) and you should be fine.

As for the offer synchronize()

, ignore it. Unless you are doing something really weird with threads and preference, or you aborted the application right after setting a value / object for the problem key, this has nothing to do with it. The first paragraph of the docs synchronize()

is called periodically as needed. In practice, this caused a lot immediately after the change.



In context, none of my apps have ever been named synchronize()

, and some are old enough to manage. No problem. Unless you have a very good excuse for calling synchronize()

yourself, you almost certainly don't need one and try to explain why you need to sprinkle it all over the place ... often funny.

In your particular case, the value got stuck after the first run several times and then suddenly more than once. Is it possible that you changed your app ID or name? The defaults are stored by id + name, so the default will be "reset" to change. Did you run your app in the simulator and you just reset -content-and-settings in the simulator? On your device and uninstall the app before re-launching it on your device?

+3


source


If you work in swift and then return nil, the objectforkey object does not get any value at all. Otherwise, it will always return the correct value if you saved the stored value correctly.



And userdefaults are always available for use, it can never be disabled.

-1


source







All Articles