2009-09-16 12 views
13

Sto lavorando su un'applicazione per iPhoneiPhone App: come ottenere il valore predefinito da root.plist?

Ho letto una chiave da root.plist come questo:

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

("Key1" è una PSMultiValueSpecifier per il quale un valore di stringa di default è stato impostato già in radice .plist)

che funziona bene, una volta che l'utente effettua le impostazioni. Ma se l'utente esegue l'app prima di eseguire qualsiasi impostazione, otterrà nil per "Chiave1". In tal caso, mi aspettavo il valore predefinito che avevo impostato per "Chiave1". cosa devo fare, in modo che l'utente non debba fare impostazioni, per far funzionare l'applicazione per la prima volta?

saluti, Harish

+0

possibile duplicato di [Si può fare le impostazioni in Impostazioni .bundle predefinito anche se non apri l'app Impostazioni] (http://stackoverflow.com/questions/510216/can-you-make-the-settings-in-settings-bundle-default-even-if-you -dont-open-the) –

+0

Per "possibile", intendo "esatto". –

risposta

13

Vedi this question per una soluzione completa.

Essenzialmente si desidera eseguire questo codice prima di accedere alla impostazione:

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

Questo caricherà i valori di default nell'oggetto standardUserDefaults in modo non sarà più tornare a zero i valori, e non si deve duplicare le impostazioni predefinite nel codice.

+0

Ho avuto lo stesso problema e questo ha funzionato per me. Grazie molto. – MaryamAyd

+0

Purtroppo questo codice non funziona in Swift 2.2 su Xcode 7.3, ricevo errori su 'stringByAppendingPathComponent' che non è disponibile. – Dai

3

faccio questo presto dopo il lancio, prima che io cerco di ottenere le mie impostazioni:

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

Ma cosa succede se il tuo percorso è il predefinito "root.plist" nel settings.bundle? – jowie

+0

Joe: Quindi ottieni un riferimento a quel pacchetto e lo mandi '-pathForResource:'. Se non puoi farlo per qualsiasi motivo, puoi semplicemente copiare il plist nelle risorse del bundle dell'app e nel bundle delle impostazioni. –

0

Nella mia applicazione delegato, ho l'override del metodo +initialize e registrare nuovi preferenze predefinite applicazione .

Ad esempio:

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

Cosa succede se si dispone di una reale risorsa settings.bundle e root.plist? – jowie

+1

@jowie purtroppo questo è necessario anche se si dispone di Settings.bundle e Root.plist. I "Valori predefiniti" specificati vengono ignorati fino a quando l'utente non apre il tuo pannello Impostazioni. Dopo una nuova installazione della tua app, prima di aprire il pannello delle impostazioni, tutti i tasti torneranno a zero a meno che non chiami manualmente "registerDefaults". – gmcnaughton

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

Perché è stato votato? – rckehoe

3

Ecco il codice che uso in iOS 7, basato pesantemente sul precedente codice Mike Weller.

mettere questo metodo nella 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]; 
} 

E poi chiamare per file ogni impostazioni che si sta utilizzando (per le impostazioni nidificate), da qualche luogo all'inizio nel codice come 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 { 

    } 
    ... 
2

Ho tradotto la soluzione Mike Weller in Swift 2.0/iOS 9 e ha reso il lavoro per la mia app:

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

A Swift 3 versione basata su Mike Weller's soluzione originale, se qualcuno ha bisogno:

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) 
} 
Problemi correlati