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