Cannot Read Default Values from Settings Bundle Until Changed by User

395 views Asked by At

In my iPhone app, I am using a settings bundle to store my app settings along with pre-defined default values. Included is, for instance, a toggle switch with the default set to true:

<dict>
    <key>Type</key>
    <string>PSToggleSwitchSpecifier</string>
    <key>Title</key>
    <string>Show score</string>
    <key>Key</key>
    <string>preference_show_score</string>
    <key>DefaultValue</key>
    <true/>
</dict>

When I retrieve this value using

let showScore = UserDefaults.standard.bool(forKey: "preference_show_score")

there are two observed outcomes:

  1. If the user has changed the setting before, the correct setting is assigned toshowScore.
  2. If the user has not touched the setting, the retrieved value is false even though the default should be true.

So, the actual setting can only be read after the user has changed it, which makes the default values redundant.

There are many SO posts on this topic, but, after reading them, I am even more confused.

Some suggest replicating the settings in the app itself, but what value does the settings app provide in this case? And, obviously, it is not entirely impossible to retrieve the settings - just not before the user has changed them.

Some other answers say that the problem is linked to not registering the defaults once with the UserDefaults before using them. Here I am uncertain how and where that should be done. I have tried this using the following statement in the AppDelegate and in the method that is reading the values itself. In fact, not using it at all did not seem to make a difference.

UserDefaults.standard.register(defaults: [String:AnyObject]())

So, with all the info I found I wonder if it is even possible to use the default values and, if yes, how it is done correctly?

And, let's say I'm forced to store the defaults also in my app, how would the app know when to use them, i.e. if the user has updated the settings?

1

There are 1 answers

1
vadian On BEST ANSWER

Registering the default values is exactly the right way. As soon as possible execute

let defaultValues = ["preference_show_score": true]
UserDefaults.standard.register(defaults: defaultValues)

The code must be executed whenever the app launches. The default value is considered until the user changes it.