Default values from settings bundle are not loaded in Xamarin.iOS

394 views Asked by At

In my project I have defined a settings.bundle containing a Root.plist with several settings, that all have default values. However on first start on a new device these defaults are shown in the settings app, but not loaded.

What's going wrong here?

1

There are 1 answers

0
JackDMF On BEST ANSWER

It turns out, that this intended. The DefaultValue specification in Settings.bundle serves only display purposes. Found on ijure.org

There you also find a solution in Objective C to get the default values and write them to the settings dictionary if a value is not present already.

I rewrote it with inspiration from this answer to a similar question:

private static void RegisterDefaultsFromSettingsBundle()
{
    var defaults = NSUserDefaults.StandardUserDefaults;
    defaults.Synchronize();

    var settingsBundle = NSBundle.MainBundle.PathForResource(@"Settings", @"bundle");

    if (string.IsNullOrEmpty(settingsBundle))
    {
        Console.WriteLine("Could not find Settings.bundle!");
        return;
    }

    var settings = NSDictionary.FromFile(settingsBundle + @"/Root.plist");
    var preferences = settings[(NSString)"PreferenceSpecifiers"] as NSArray;

    using (var defaultsToRegister = new NSMutableDictionary())
    {
        if (preferences != null)
        {
            foreach (var prefItem in NSArray.FromArray<NSDictionary>(preferences))
            {
                var key = prefItem[(NSString) "Key"] as NSString;

                if (key != null)
                {
                    var currentObject = defaults[key];
                    if (currentObject == null)
                    {
                        // Not yet set in the defaults
                        var defaultValue = prefItem[@"DefaultValue"];
                        defaultsToRegister.Add(key, defaultValue);
                        Console.WriteLine($"Setting value '{defaultValue}' for key '{key}'");
                    }
                    else
                    {
                        // Already set in the defaults: don't touch
                        Console.WriteLine($"Key '{key}' is readable (value: '{currentObject}'), nothing written to defaults.");
                    }
                }
            }
        }

        defaults.RegisterDefaults(defaultsToRegister);
    }
    defaults.Synchronize();
}

Hope this helps someone