2009-09-16 84 views
13

我在iPhone上的應用程序iPhone應用程序:如何從root.plist獲取默認值?

工作,我讀了root.plist這樣的關鍵:

NSString *Key1Var = [[NSUserDefaults standardUserDefaults] stringForKey:@"Key1"]; 

(「密鑰1」是其默認字符串值已經設置在根PSMultiValueSpecifier .plist)

一旦用戶進行設置,就可以正常工作。 但是,如果用戶在執行任何設置之前運行應用程序,他將獲得「Key1」的nil。 在這種情況下,我期待着我爲「Key1」設置的默認值。 我需要做什麼, 這樣用戶不必做設置,讓應用程序第一次運行?

問候, 哈里什

+0

可能重複.bundle默認即使你不打開設置應用程序](http://stackoverflow.com/questions/510216/can-you-make-the-settings-in-settings-bundle-default-even-if-you -dont-open-the) – 2012-05-08 11:38:23

+0

'可能',我的意思是'確切'。 – 2012-05-08 11:45:39

回答

13

的完整解決方案見this question

你基本上要訪問設置之前,運行此代碼:

- (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]; 
} 

這將默認值加載到standardUserDefaults對象,所以你不會再回到零值,而你不必複製代碼中的默認設置。

+0

我有同樣的問題,這對我工作。非常感謝。 – MaryamAyd 2012-08-14 14:26:58

+0

不幸的是,這段代碼在Xcode 7.3的Swift 2.2中不起作用,我得到關於'stringByAppendingPathComponent'不可用的錯誤。 – Dai 2016-03-27 23:38:49

3

我做到這一點推出後初期,在我試圖讓我的設置:

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"); 
+0

但是如果你的路徑是settings.bundle中默認的「root.plist」呢? – jowie 2010-08-31 14:38:15

+0

Joe:然後你得到這個包的引用併發送它'-pathForResource:'。如果因爲任何原因無法這樣做,您可以將plist複製到應用程序包的資源以及設置包中。 – 2010-09-25 00:06:16

0

在我的應用程序委託,我重寫+initialize方法並註冊新的應用程序默認偏好。

例如:

+ (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]; 
    } 
} 
+1

如果你有一個實際的settings.bundle和root.plist資源,該怎麼辦? – jowie 2010-08-31 14:38:49

+1

@jowie可惜這是必需的,即使你有一個Settings.bundle和Root.plist。在用戶打開「設置」窗格之前,將忽略此處指定的「默認值」。全新安裝應用程序後,在打開設置窗格之前,除非手動調用「registerDefaults」,否則所有鍵都將返回nil。 – gmcnaughton 2013-12-31 17:26:41

0
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]; 
+1

這是爲什麼被拒絕? – rckehoe 2013-12-06 14:54:56

3

下面是我在iOS 7中使用的代碼,主要基於上面的Mike Weller的代碼。在你的代碼

- (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]; 
} 

然後調用它的每一個設置文件正在使用(嵌套設置),從一些地方早期像didFinishLaunchingWithOptions:

將這個方法在你AppDelegate.m

- (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 { 

    } 
    ... 
2

我把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) 
} 
1

迅速3版本的基礎上Mike Weller's原來的解決方案,如果有人需要它:

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) 
} 
的[你可以在設置中設置