I solved this by using the method detailed in this question:
Can you make the settings in Settings.bundle default even if you don't open the Settings App
I basically translated the function registerDefaultsFromSettingsBundle listed there into MonoTouch. This is a very useful function because it calls registerDefaults for the default values listed in the settings bundle. This ensures that if the user has not entered any values, that the defined default values will be returned rather than null values. This can be called from FinishedLaunching of the AppDelegate.
Here is the MonoTouch version of this function:
public static void RegisterDefaultsFromSettingsBundle()
{
string settingsBundle = NSBundle.MainBundle.PathForResource("Settings", @"bundle");
if(settingsBundle == null) {
System.Console.WriteLine(@"Could not find Settings.bundle");
return;
}
NSString keyString = new NSString(@"Key");
NSString defaultString = new NSString(@"DefaultValue");
NSDictionary settings = NSDictionary.FromFile(Path.Combine(settingsBundle,@"Root.plist"));
NSArray preferences = (NSArray) settings.ValueForKey(new NSString(@"PreferenceSpecifiers"));
NSMutableDictionary defaultsToRegister = new NSMutableDictionary();
for (uint i=0; i<preferences.Count; i++) {
NSDictionary prefSpecification = new NSDictionary(preferences.ValueAt(i));
NSString key = (NSString) prefSpecification.ValueForKey(keyString);
if(key != null) {
NSObject def = prefSpecification.ValueForKey(defaultString);
if (def != null) {
defaultsToRegister.SetValueForKey(def, key);
}
}
}
NSUserDefaults.StandardUserDefaults.RegisterDefaults(defaultsToRegister);
}
I hope other MonoTouch developers find this useful.
UPDATE:
With the latest version of Xamarin.iOS this code will throw an exception on this line:
NSDictionary prefSpecification = new NSDictionary(preferences.ValueAt(i));
Note that this exception does not occur because of iOS 8 but because Xamarin has decided to make the constructor that the code is depending on private, so the required constructor is not available to be used. I resolved this by subclassing NSDictionary like this:
public class CustomNSDictionary: NSDictionary
{
public CustomNSDictionary (IntPtr ptr): base(ptr) {}
}
Then you can replace the problematic line with the following:
CustomNSDictionary prefSpecification = new CustomNSDictionary(preferences.ValueAt(i));