Search code examples
iphoneobjective-cnsuserdefaultspreferencesapplication-settings

How to Change iphone Application Preferences Settings at run time?


Objective: I want to set iphone Application Preferences at run time

In Setting.Bundle I have title=Version and DefaultValue=1.0

So at run time if there is new version available i have to change iphone Application Preference Default Value. But i am not able to do so. It showing 1.0 instead of 1.1

I dont know whats wrong in my code

Code:

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

        if([key isEqualToString:@"name_preference"])
        {
            NSString *a=[[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleVersion"];
            [defaultsToRegister setObject:a forKey:key];
        }
        else {
            [defaultsToRegister setObject:[prefSpecification objectForKey:@"DefaultValue"] forKey:key];

        }


    }
}

[[NSUserDefaults standardUserDefaults] registerDefaults:defaultsToRegister];

Solution

  • Your bundle is read-only, so anything you want to write needs to be externalized. You can use Standard Defaults to keep all that information if you want to. That is pretty straightforward:

    NSString *version = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleShortVersionString"];
    NSString *build = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleVersion"];
    [standardDefaults setObject: build forKey:@"MyAppBuild"];
    [standardDefaults setObject: version forKey:@"MyAppVersion"];
    [standardDefaults synchronize]; 
    

    Additionally, you can copy a plist to the device file system and read and write to/from that:

    Reading:

    + (NSDictionary *) loadAppData {
        NSString *finalPath;
    
        // Load "defaults" plist
        NSArray *paths =  NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
        NSString *documentsPath = [paths objectAtIndex:0]; 
        NSString *writablePath = [documentsPath stringByAppendingPathComponent:@"AppSettings.plist"];
    
        NSFileManager *fileManager = [NSFileManager defaultManager];
        if([fileManager fileExistsAtPath: writablePath]){
            finalPath = writablePath;
        }
        else{
            NSString *path = [[NSBundle mainBundle] bundlePath];
            finalPath = [path stringByAppendingPathComponent:@"AppSettings.plist"];
        }
    
        return [NSDictionary dictionaryWithContentsOfFile: finalPath];
    }
    

    Writing:

    + (void) saveAppData: (NSDictionary *) appData {
    
        // Load "defaults" plist
        NSArray *paths =  NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
        NSString *documentsPath = [paths objectAtIndex:0]; 
        NSString *writablePath = [documentsPath stringByAppendingPathComponent:@"AppSettings.plist"];
    
        // Save it
        [appData writeToFile: writablePath atomically: YES];
    }