xcode iPhone 应用程序:如何从 root.plist 获取默认值?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1431148/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
iPhone App : How to get default value from root.plist?
提问by Harish J
I am working on an iPhone app
我正在开发 iPhone 应用程序
I read a key from root.plist like this :
我从 root.plist 中读取了一个密钥,如下所示:
NSString *Key1Var = [[NSUserDefaults standardUserDefaults] stringForKey:@"Key1"];
("Key1" is a PSMultiValueSpecifier
for which a default string value has been set already in root.plist)
(“Key1”是PSMultiValueSpecifier
已经在 root.plist 中设置了默认字符串值的一个)
That works fine, once the user makes settings.
But if the user runs the app before he does any setting, he will get nil
for "Key1".
In such case, I was expecting the default value that i had set for "Key1".
what i need to do,
so that the user does not have to do setting, to make application run for the first time?
一旦用户进行设置,就可以正常工作。但是如果用户在进行任何设置之前运行该应用程序,他将获得nil
“Key1”。在这种情况下,我期待我为“Key1”设置的默认值。我需要做什么,以便用户不必进行设置,使应用程序首次运行?
Regards, Harish
问候, 哈里斯
回答by Mike Weller
See this questionfor a complete solution.
请参阅此问题以获得完整的解决方案。
You essentially want to run this code before accessing the setting:
您基本上希望在访问设置之前运行此代码:
- (void)registerDefaultsFromSettingsBundle {
NSString *settingsBundle = [[NSBundle mainBundle] pathForResource:@"Settings" ofType:@"bundle"];
if(!settingsBundle) {
NSLog(@"Could not find Settings.bundle");
return;
}
NSDictionary *settings = [NSDictionary dictionaryWithContentsOfFile:[settingsBundle stringByAppendingPathComponent:@"Root.plist"]];
NSArray *preferences = [settings objectForKey:@"PreferenceSpecifiers"];
NSMutableDictionary *defaultsToRegister = [[NSMutableDictionary alloc] initWithCapacity:[preferences count]];
for(NSDictionary *prefSpecification in preferences) {
NSString *key = [prefSpecification objectForKey:@"Key"];
if(key) {
[defaultsToRegister setObject:[prefSpecification objectForKey:@"DefaultValue"] forKey:key];
}
}
[[NSUserDefaults standardUserDefaults] registerDefaults:defaultsToRegister];
[defaultsToRegister release];
}
This will load the default values into the standardUserDefaults
object so you will no longer get back nil values, and you don't have to duplicate the default settings in your code.
这会将默认值加载到standardUserDefaults
对象中,因此您将不再返回 nil 值,并且您不必在代码中复制默认设置。
回答by mahboudz
I do this early after launch, before I try to get my settings:
我在发布后尽早执行此操作,然后再尝试获取我的设置:
userDefaultsValuesPath=[[NSBundle mainBundle] pathForResource:@"UserDefaults"
ofType:@"plist"];
userDefaultsValuesDict=[NSDictionary dictionaryWithContentsOfFile:userDefaultsValuesPath];
// set them in the standard user defaults
[[NSUserDefaults standardUserDefaults] registerDefaults:userDefaultsValuesDict];
if (![[NSUserDefaults standardUserDefaults] synchronize])
NSLog(@"not successful in writing the default prefs");
回答by Coty Condry
Here is the code I use in iOS 7, based heavily on Mike Weller's code above.
这是我在 iOS 7 中使用的代码,主要基于上面Mike Weller的代码。
Put this method in your AppDelegate.m:
将此方法放在您的 AppDelegate.m 中:
- (void)registerDefaultsFromSettingsBundleWithPlist:(NSString *)plist {
NSString *settingsBundle = [[NSBundle mainBundle] pathForResource:@"Settings" ofType:@"bundle"];
if(!settingsBundle) {
NSLog(@"Could not find Settings.bundle");
return;
}
NSString *bundle = [NSString stringWithFormat:@"%@.plist",plist];
NSDictionary *settings = [NSDictionary dictionaryWithContentsOfFile:[settingsBundle stringByAppendingPathComponent:bundle]];
NSArray *preferences = [settings objectForKey:@"PreferenceSpecifiers"];
NSMutableDictionary *defaultsToRegister = [[NSMutableDictionary alloc] initWithCapacity:[preferences count]];
for(NSDictionary *prefSpecification in preferences) {
NSString *key = [prefSpecification objectForKey:@"Key"];
if(key) {
[defaultsToRegister setObject:[prefSpecification objectForKey:@"DefaultValue"] forKey:key];
}
}
[[NSUserDefaults standardUserDefaults] registerDefaults:defaultsToRegister];
//[defaultsToRegister release];
}
And then call it for every settings file you're using (for nested settings), from some place early in your code like didFinishLaunchingWithOptions:
然后为您正在使用的每个设置文件(对于嵌套设置)调用它,从代码早期的某个地方,如 didFinishLaunchingWithOptions:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
//register default settings into NSUserDefaults
@try {
[self registerDefaultsFromSettingsBundleWithPlist:@"Root"];
[self registerDefaultsFromSettingsBundleWithPlist:@"Chat"];
[self registerDefaultsFromSettingsBundleWithPlist:@"IVR"];
[self registerDefaultsFromSettingsBundleWithPlist:@"Video"];
}
@catch (NSException * e) {
NSLog(@"Exception: %@", e);
NSLog(@"Try adding the Default Value field to each preference item in the Settings.bundle plist files.");
}
@finally {
}
...
回答by Andrew Lombard
A Swift 3 version based on Mike Weller'soriginal solution if anyone needs it:
如果有人需要,基于Mike Weller 的原始解决方案的 Swift 3 版本:
static func registerDefaultsFromSettingsBundle() {
guard let settingsBundle = Bundle.main.url(forResource: "Settings", withExtension: "bundle") else {
print("Could not find Settings.bundle")
return
}
guard let settings = NSDictionary(contentsOf: settingsBundle.appendingPathComponent("Root.plist")) else {
print("Couldn't find Root.plist in settings bundle")
return
}
guard let preferences = settings.object(forKey: "PreferenceSpecifiers") as? [[String: AnyObject]] else {
print("Root.plist has an invalid format")
return
}
var defaultsToRegister = [String: AnyObject]()
for var p in preferences {
if let k = p["Key"] as? String, let v = p["DefaultValue"] {
print("Registering " + v.debugDescription + " for key " + k)
defaultsToRegister[k] = v as AnyObject
}
}
UserDefaults.standard.register(defaults: defaultsToRegister)
}
回答by BaseZen
I've translated Mike Weller's solution into Swift 2.0/iOS 9 and made it work for my App:
我已将Mike Weller的解决方案翻译成 Swift 2.0/iOS 9 并使其适用于我的应用程序:
func registerDefaultsFromSettingsBundle() {
guard let settingsBundle = NSBundle.mainBundle().URLForResource("Settings", withExtension:"bundle") else {
NSLog("Could not find Settings.bundle")
return;
}
guard let settings = NSDictionary(contentsOfURL: settingsBundle.URLByAppendingPathComponent("Root.plist")) else {
NSLog("Could not find Root.plist in settings bundle")
return
}
guard let preferences = settings.objectForKey("PreferenceSpecifiers") as? [[String: AnyObject]] else {
NSLog("Root.plist has invalid format")
return
}
var defaultsToRegister = [String: AnyObject]()
for var p in preferences {
if let k = p["Key"] as? String, v = p["DefaultValue"] {
NSLog("%@", "registering \(v) for key \(k)")
defaultsToRegister[k] = v
}
}
NSUserDefaults.standardUserDefaults().registerDefaults(defaultsToRegister)
}
回答by Alex Reynolds
In my application delegate, I override the +initialize
method and register new application default preferences.
在我的应用程序委托中,我覆盖了该+initialize
方法并注册了新的应用程序默认首选项。
For example:
例如:
+ (void) initialize {
if ([self class] == [MyAppDelegate class]) {
// initialize user defaults dictionary
BOOL isFirstTimeRun = YES;
BOOL isKeychainTurnedOn = NO;
BOOL isSSLTurnedOn = YES;
NSString *testURLString = @"http://stackoverflow.com";
NSMutableDictionary *resourceDict = [NSMutableDictionary dictionary];
[resourceDict setObject:[NSNumber numberWithBool:isFirstTimeRun] forKey:kIsFirstTimeRunKey];
[resourceDict setObject:[NSNumber numberWithBool:isKeychainTurnedOn] forKey:kIsKeychainTurnedOnKey];
[resourceDict setObject:[NSNumber numberWithBool:isSSLTurnedOn] forKey:kIsSSLTurnedOnKey];
[resourceDict setObject:testURLString forKey:kTestURLString];
[[NSUserDefaults standardUserDefaults] registerDefaults:resourceDict];
}
}
回答by Nikhil Dinesh
NSBundle* mainBundle = [NSBundle mainBundle];?
?
?
// Reads the value of the custom key I added to the Info.plist
NSString *value = [mainBundle objectForInfoDictionaryKey:@"key"];
//Log the value
NSLog(@"Value = %@", value);
// Get the value for the "Bundle version" from the Info.plist
[mainBundle objectForInfoDictionaryKey:@"CFBundleVersion"];
// Get the bundle identifier
[mainBundle bundleIdentifier];