使用InAppSettingsKit时遇到读取设置问题

我正在使用InAppSettingsKit模块来pipe理我的设置。

我可以将其包含在我的项目中,以便可以build立与我的项目正确交互的设置页面。 我有一个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]说,所以我不知所措。

我认为你的问题依赖于对这个概念的误解。 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]; 

这里是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]; } 

这一切都是有道理的。 我曾尝试注册以前的尝试,以使事情工作的默认值,但我想我可以做到这一点使用Root.plist文件。 但是,当然,registerDefaults方法只能看到StringsTable和PreferenceSpecifiers的高级条目。 感谢您指出这Ortwin。

因此,我没有build立一个单独的userDefault.plist文件,而是find了下面的代码来parsingroot.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]; } } 

我修改了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]; } 

我已经根据@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() } } 

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

在你的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]; 

}