如何在MonoTouch中注册默认值?

Bru*_*ill 12 iphone xamarin.ios

我想在NSUserDefaults中注册默认值,以便用户设置不会为未由用户显式设置的值返回空值,而是返回设置包中指定的默认值.我在这里读到:

如何在不覆盖现有值的情况下使用NSUserDefaults注册用户默认值?

应该在applicationDidFinishLaunching中执行以下内容:

[[NSUserDefaults standardUserDefaults] registerDefaults:[NSDictionary dictionaryWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"Defaults" ofType:@"plist"]]];
Run Code Online (Sandbox Code Playgroud)

如何在MonoTouch中完成?

Bru*_*ill 15

我通过使用此问题中详述的方法解决了这个问题:

即使您未打开"设置应用",也可以在Settings.bundle默认设置中进行设置

我基本上将那里列出的函数registerDefaultsFromSettingsBundle翻译成MonoTouch.这是一个非常有用的函数,因为它调用registerDefaults作为设置包中列出的默认值.这可确保如果用户未输入任何值,则将返回定义的默认值而不是空值.这可以从AppDelegate的FinishedLaunching调用.

以下是此功能的MonoTouch版本:

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);
}
Run Code Online (Sandbox Code Playgroud)

我希望其他MonoTouch开发人员认为这很有用.

更新:

使用Xamarin.iOS此代码的最新版本将在此行上引发异常:

NSDictionary prefSpecification = new NSDictionary(preferences.ValueAt(i));
Run Code Online (Sandbox Code Playgroud)

请注意,iOS 8由于Xamarin已决定使代码依赖于私有的构造函数,因此不会发生此异常,因此无法使用所需的构造函数.我通过子类化解决了NSDictionary这个问题:

public class CustomNSDictionary: NSDictionary 
{
    public CustomNSDictionary (IntPtr ptr): base(ptr) {}
}
Run Code Online (Sandbox Code Playgroud)

然后,您可以使用以下内容替换有问题的行:

CustomNSDictionary prefSpecification = new CustomNSDictionary(preferences.ValueAt(i));
Run Code Online (Sandbox Code Playgroud)

  • 感谢您发布已翻译的代码.我目前正在使用iOS 8,并且在以下代码行中遇到了一个问题:NSDictionary prefSpecification = new NSDictionary(preferences.ValueAt(i));`似乎在最新版本的iOS中,NSDictionary不再接受其中的IntPtr构造函数.它只接受NSCoder,NSDictionary,NSUrl或字符串.在使用不同参数类型的多次尝试后,我无法使其工作.如何以NSDicionary可以理解的方式格式化IntPtr? (2认同)
  • 嗨肖恩.我最近也遇到过这个问题.这是我发布的关于它的stackoverflow问题:http://stackoverflow.com/questions/29959439/cannot-access-protected-member-foundation-nsdictionary-nsdictionarysystem-intp我将发布一个更新,显示我是如何通过子类化解决它的NSDictionary并在子类中使所需的构造函数公开. (2认同)

Luk*_*uke 2

您可以尝试以下方法:

NSUserDefaults.StandardUserDefaults.RegisterDefaults(NSDictionary.FromFile("Defaults.plist"));
Run Code Online (Sandbox Code Playgroud)

(假设您已经创建了一个 Defaults.plist 文件,其中包含所有默认值!(并且它位于捆绑包的根目录中!))