문제

I've developped an application that use a Settings.bundle to allow users to change some stuff within the application.

For exemple :

I've a parameter with the key "firstName", the DefaultValue is "John". User can change "John" by "Bryan" within Settings pane and see "Hello Bryan!" in my application. Yipie !

If user update my application without remove it before, when he will launch app again, the text "Hello Bryan!" still there. This is normal because of the MyApp.app/Library/Preferences/my.bundle.com.MyApp.plist

When the datas has been changed by the users, they were stored in this file and will be stored until the user remove the app from his device (not just an update).

My problem is that, after my app update, I don't want user see "Hello Bryan !" but the DefaultValue instead (John) only if I decide.

To do that I think about this solution :

NSDictionary* infoDict = [[NSBundle mainBundle] infoDictionary];

NSString* currentVersion = [infoDict objectForKey:@"CurrentSettingsVersion"];

NSString*storedVersion =  [[NSUserDefaults standardUserDefaults] objectForKey:@"currentSettingsVersion"];

BOOL sameVersion = nil;

if([currentVersion isEqualToString:storedVersion]){
    //No change keep preference
    sameVersion = YES;
}else{
    //Versions are different => erase prefs and set new currentSettingsVersion number
    sameVersion = NO;
    //Reset
    [[NSUserDefaults standardUserDefaults] setValue:currentVersion forKey:@"currentSettingsVersion"];
}

When current version is different from stored version, I try to figure out not how can I reset this file but if it's ok with Apple specifications ?? MyApp.app/Library/Preferences/my.bundle.com.MyApp.plist

I known this is weird but my client does not want to uninstall application before update it. The really case is that in my first app version there is a Settings.bundle and in the second version there is not. But our application keep the changed settings in memory despite there is not Settings.bundle anymore.

I hope you understand ;) this is a really weird demands :)

Pebie

도움이 되었습니까?

해결책 2

Thanks,

My solution regarding versioning is right. But when I call [NSUserDefaults resetStandardUserDefaults] application crash. Instead of that I call :

NSString *domainName = [[NSBundle mainBundle] bundleIdentifier];
[[NSUserDefaults standardUserDefaults] removePersistentDomainForName:domainName];

Then I reset currentVersion and storedVersion to the same value.

It's OK !

Thanks

다른 팁

There is a method [NSUserDefaults resetStandardUserDefaults] which completely removes all stored settings.

Your solution regarding versioning is completely right, you can keep your app version within NSUserDefaults, check it on every app launch, do migration if the version is different and store your current app version back. If there's no version in NSUserDefault then it's a fresh installation launch, so you do not do anything.

Once I had to implement a similar mechanism for version-to-version migrations, because if you update your app more than once and you need some data migration on every update then you need more powerful mechanism, not just a flag that says same version or not. so I wrote two functions that split and compare a version string on N components. version_compare can be also used in NSArray sort operations, so I had basically special object that performed data migration for each version, I was looking for current version, sorting all released versions of the app and incrementally performing migration.

#define MAX_VERSION_DIGITS 3

static void parse_version_string(NSString* version, int(*numbers)[MAX_VERSION_DIGITS])
{
    int seq[MAX_VERSION_DIGITS] = { 0, 0, 0 };
    NSArray* split = [version componentsSeparatedByString:@"."];

    for(int i = 0, c = MIN(MAX_VERSION_DIGITS, split.count); i < c; i++) 
    {
        seq[i] = [[split objectAtIndex:i] intValue];
    }

    memcpy(numbers, &seq, sizeof(seq));
}

static NSComparisonResult version_compare(NSString* a, NSString* b)
{
    int seq1[MAX_VERSION_DIGITS];
    int seq2[MAX_VERSION_DIGITS];

    parse_version_string(a, &seq1);
    parse_version_string(b, &seq2);

    for(int i = 0; i < MAX_VERSION_DIGITS; i++) 
    {
        if(seq1[i] > seq2[i]) 
        {
            return NSOrderedDescending;
        } 
        else if(seq1[i] < seq2[i]) 
        {
            return NSOrderedAscending;
        }
    }

    return NSOrderedSame;
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top