5

我正在使用这些InAppSettingsKit模块来管理我的设置。

我可以将它包含在我的项目中,以便我可以构建一个与我的项目正确交互的设置页面。我有一个可以更改的 root.plist,当我第一次在模拟器上运行我的应用程序时,我可以看到反映的更改。

但是,对于我的生活,我无法NSUserDefaults通过我的代码访问设置。当我运行下面的代码时,我可以遍历[NSUserDefaults standardUserDefaults]. 但是,我只看到一堆与我的 plist 文件中的内容无关的通用设置

NSUserDefaults* d = [NSUserDefaults standardUserDefaults];

NSDictionary* dict = [d dictionaryRepresentation];

NSString* descKey;
NSString* descObject;
NSString* classTypeForKey;
NSString* classTypeForObject;
id myObject;

for (id key in dict) {
    myObject = [dict objectForKey:key];
    classTypeForObject = [[myObject class] description];
    classTypeForKey = [[key class] description];
    descKey = [key description];
    descObject = [myObject description];
}

那么 InAppSettingsKit 将设置放在哪里呢?医生说,[NSUserDefaults standardUserDefaults]所以我很茫然。

4

6 回答 6

6

I think your problem relies on a misunderstanding of the concept. Root.plist doesn't store any settings but just defines how Settings.app and InAppSettingsKit work on your userDefaults.

When your app launches the first time, there are no userDefaults. Usually, you start by setting appropriate default settings by reading in a static userDefaults.plist from your Resources:

// Load the default values for the user defaults
NSString* pathToUserDefaultsValues = [[NSBundle mainBundle]
                                      pathForResource:@"userDefaults" 
                                      ofType:@"plist"];
NSDictionary* userDefaultsValues = [NSDictionary dictionaryWithContentsOfFile:pathToUserDefaultsValues];

// Set them in the standard user defaults
[[NSUserDefaults standardUserDefaults] registerDefaults:userDefaultsValues];
于 2011-07-12T23:00:20.443 回答
4

这是 Ojas 的代码,为了解释 ARC 做了进一步的修改。

您可能会从 AppDelegate didFinishLaunchingWithOptions 调用 initializeSettings。

#import "IASKSettingsReader.h"
...

- (void)initializeSettings
{
    // standard stored preference values
    NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];

    // settings files to process
    NSMutableArray *preferenceFiles = [[NSMutableArray alloc] init];

    // begin with Root file
    [preferenceFiles addObject:@"Root"];

    // as other settings files are discovered will be added to preferencesFiles
    while ([preferenceFiles count] > 0) {

        // init IASKSettingsReader for current settings file
        NSString *file = [preferenceFiles lastObject];
        [preferenceFiles removeLastObject];
        IASKSettingsReader *settingsReader = [[IASKSettingsReader alloc]
                                              initWithFile:file];

        // extract preference specifiers
        NSArray *preferenceSpecifiers = [[settingsReader settingsBundle]
                                         objectForKey:kIASKPreferenceSpecifiers];

        // process each specifier in the current settings file
        for (NSDictionary *specifier in preferenceSpecifiers) {

            // get type of current specifier
            NSString *type = [specifier objectForKey:kIASKType];

            // need to check child pane specifier for additional file
            if ([type isEqualToString:kIASKPSChildPaneSpecifier]) {
                [preferenceFiles addObject:[specifier objectForKey:kIASKFile]];
            }
            else {
                // check if current specifier has a default value
                id defaultValue = [specifier objectForKey:kIASKDefaultValue];

                if (defaultValue) {
                    // get key from specifier and current stored preference value
                    NSString *key = [specifier objectForKey:kIASKKey];
                    id value = [defaults objectForKey:key];

                    // update preference value with default value if necessary
                    if (key && value == nil) {
                        [defaults setObject:defaultValue forKey:key];
                    }
                }
            }

        }

    }

    // synchronize stored preference values
    [defaults synchronize];
}
于 2012-10-10T14:11:34.383 回答
3

现在一切都说得通了。在之前的尝试中,我曾尝试注册默认值以使事情正常进行,但我认为我可以使用 Root.plist 文件来做到这一点。但当然 registerDefaults 方法只看到 StringsTable 和 PreferenceSpecifiers 的高级条目。感谢您指出 Ortwin。

因此,我没有构建单独的 userDefault.plist 文件,而是找到了以下代码来解析 root.plist 文件以手动将默认值添加到 NSUserDefaults。我不记得我在哪里得到它,但它似乎运作良好。如果有我不应该这样做的原因,请随时详细说明:

    - (void)setDefaults {

        //get the plist location from the settings bundle
        NSString *settingsPath = [[[NSBundle mainBundle] bundlePath] stringByAppendingPathComponent:@"Settings.bundle"];
        NSString *plistPath = [settingsPath stringByAppendingPathComponent:@"Root.plist"];

        //get the preference specifiers array which contains the settings
        NSDictionary *settingsDictionary = [NSDictionary dictionaryWithContentsOfFile:plistPath];
        NSArray *preferencesArray = [settingsDictionary objectForKey:@"PreferenceSpecifiers"];

        //use the shared defaults object
        NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];

        //for each preference item, set its default if there is no value set
        for(NSDictionary *item in preferencesArray) {

            //get the item key, if there is no key then we can skip it
            NSString *key = [item objectForKey:@"Key"];
            if (key) {

                //check to see if the value and default value are set
                //if a default value exists and the value is not set, use the default
                id value = [defaults objectForKey:key];
                id defaultValue = [item objectForKey:@"DefaultValue"];
                if(defaultValue && !value) {
                    [defaults setObject:defaultValue forKey:key];
                }
            }
        }

        //write the changes to disk
        [defaults synchronize];
        }
}
于 2011-07-15T00:02:50.343 回答
2

我修改了 Sam 的代码以处理在单独文件中指定的子窗格:

#import "IASKSettingsReader.h"

- (void)initializeSettings
{
    // standard stored preference values
    NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];

    // settings files to process
    NSMutableArray *preferenceFiles = [[NSMutableArray alloc] init];

    // begin with Root file
    [preferenceFiles addObject:@"Root"];

    // as other settings files are discovered will be added to preferencesFiles
    while (![preferenceFiles isEmpty]) {

        // init IASKSettingsReader for current settings file
        NSString *file = [[preferenceFiles lastObject] retain];
        [preferenceFiles removeLastObject];
        IASKSettingsReader *settingsReader = [[IASKSettingsReader alloc]
                                              initWithFile:file];
        [file release];

        // extract preference specifiers
        NSArray *preferenceSpecifiers = [[settingsReader settingsBundle] 
                                         objectForKey:kIASKPreferenceSpecifiers]; 

        // process each specifier in the current settings file
        for (NSDictionary *specifier in preferenceSpecifiers) {

            // get type of current specifier
            NSString *type = [specifier objectForKey:kIASKType];

            // need to check child pane specifier for additional file
            if ([type isEqualToString:kIASKPSChildPaneSpecifier]) {
                [preferenceFiles addObject:[specifier objectForKey:kIASKFile]];
            }
            else {
                // check if current specifier has a default value
                id defaultValue = [specifier objectForKey:kIASKDefaultValue];

                if (defaultValue) {
                    // get key from specifier and current stored preference value
                    NSString *key = [specifier objectForKey:kIASKKey];
                    id value = [defaults objectForKey:key];

                    // update preference value with default value if necessary
                    if (key && value == nil) {
                        [defaults setObject:defaultValue forKey:key];                        
                    }
                }
            }

        }

        [settingsReader release];
    }

    [preferenceFiles release];

    // synchornize stored preference values
    [defaults synchronize];
}
于 2012-02-12T22:58:45.933 回答
1

我的答案基于@Ojas 给出的答案。但我将其转换为 Swift。我希望这对使用 Swift 的人有用

func processDefaultSettings() {

    let defaults = IASKSettingsStoreUserDefaults().defaults

    // settings files to process
    var preferenceFiles = [String]()

    // begin with Root file
    preferenceFiles.append("Root")

    // as other settings files are discovered will be added to preferencesFiles
    while !preferenceFiles.isEmpty {

        // init IASKSettingsReader for current settings file
        let file = preferenceFiles.last
        let settingsReader = IASKSettingsReader(file: file)
        preferenceFiles.removeLast()

        // extract preference specifiers
        if let preferenceSpecfiers = settingsReader.settingsDictionary[kIASKPreferenceSpecifiers] as? NSArray {

            // process each specifier in the current settings file
            for specifier in preferenceSpecfiers {

                // get type of current specifier
                let type = specifier[kIASKType] as! String

                // need to check child pane specifier for additional file
                if type == kIASKPSChildPaneSpecifier {
                    preferenceFiles.append(specifier[kIASKFile] as! String)
                }
                else {
                    // check if current specifier has a default value
                    if let defaultValue = specifier[kIASKDefaultValue] as AnyObject? {

                        // get key from specifier and current stored preference value
                        if let key = specifier[kIASKKey] as? String {

                            if let value = defaults.objectForKey(key) {
                                // Nothing to do - already set
                            }
                            else {
                                let appDefaults = [key: defaultValue]
                                defaults.registerDefaults(appDefaults)
                            }
                        }
                    }
                }
            }
        }
        // synchornize stored preference values
        defaults.synchronize()
    }
}
于 2015-07-18T15:13:40.870 回答
0

我在上面修改了史蒂夫对他自己问题的回答,以下似乎对我有用:

在您的 IASKAppSettingsViewController 子类中-

- (void)viewDidLoad
{
    [super viewDidLoad];


    NSDictionary* settingsBundle = [self.settingsReader settingsBundle];
    NSArray *preferencesArray = [settingsBundle objectForKey:@"PreferenceSpecifiers"];
    NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];

    //for each preference item, set its default if there is no value set
    for(NSDictionary *item in preferencesArray) {

        //get the item key, if there is no key then we can skip it
        NSString *key = [item objectForKey:@"Key"];
        if (key) {

            //check to see if the value and default value are set
            //if a default value exists and the value is not set, use the default
            id value = [defaults objectForKey:key];
            id defaultValue = [item objectForKey:@"DefaultValue"];
            if(defaultValue && !value) {
                [defaults setObject:defaultValue forKey:key];
            }
        }
    }

    //write the changes to disk
    [defaults synchronize];

}

于 2012-02-01T11:56:18.777 回答