使用InAppSettingsKit时读取设置时出现问题

时间:2011-07-12 16:48:35

标签: ios iphone objective-c nsuserdefaults inappsettingskit

我正在使用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]中说,所以我不知所措。

6 个答案:

答案 0 :(得分:6)

我认为你的问题依赖于对这个概念的误解。 Root.plist不存储任何设置,只是定义了Settings.app和InAppSettingsKit如何在userDefaults上工作。

当您的应用首次启动时,没有userDefaults。通常,您可以通过从资源中读取静态userDefaults.plist来设置适当的默认设置:

// 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];

答案 1 :(得分: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];
}

答案 2 :(得分:3)

现在一切都有意义了。我曾尝试在以前的尝试中注册默认值以使事情正常工作,但我想我可以使用Root.plist文件来完成此操作。但是当然registerDefaults方法只能看到StringsTable和PreferenceSpecifiers的高级条目。谢谢你指出Ortwin。

因此,我发现以下代码解析root.plist文件而不是构建单独的userDefault.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];
        }
}

答案 3 :(得分: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];
}

答案 4 :(得分:1)

我的答案基于@Ojas给出的答案。但我把它改成了斯威夫特。我希望这对使用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()
    }
}

答案 5 :(得分: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];

}