Подтвердить что ты не робот

Обновление базы данных sqlite при изменении версии приложения на Appstore в iPhone

У меня есть приложение с версией 1.0 в хранилище приложений, которое использует базу данных sqlite для чтения данных.
Теперь я хочу обновить мою версию до версии 1.1 с обновлением в файле базы данных.
При использовании сертификата разработчика, когда Я устанавливаю приложение на устройство, которое не обновляло базу данных, поскольку файл базы данных уже существует в папке с документами, поэтому мне нужно вручную удалить приложение и установить его снова.
Мой вопрос: когда пользователь обновляет приложение, База данных также обновляется в соответствии с текущей версией.
Любые предложения приветствуются.
Спасибо

4b9b3361

Ответ 1

Я уверен, что есть много способов сделать это (и многие способы лучше, чем мои), но способ, которым я занимаюсь такими проблемами, выглядит следующим образом:

Сначала я определяю константу в первом файле .h файла приложения (тот, который будет загружаться первым), чтобы указать нагрузку первого времени, и установите ее на 0:

#define FirstTime 0

Теперь вам нужно знать, что у меня есть намерение сохранить значение этой константы в папке "Документы" для будущих ссылок, поэтому я использую экземпляр общих данных. В viewDidLoad я делаю следующее испытание:

//if first time run of this version
if( [MyDataModel sharedInstance].count < (FirstTime + 1) )
{
    //do what you need to do as the first time load for this version

    [MyDataModel sharedInstance].count++
    //save the count value to disk so on next run you are not first time
    //this means count = 1
}

Теперь ваш трюк находится в вашей новой версии приложения (скажем, 1.1). Я изменяю FirstTime на 2:

#define FirstTime 2

Так как сохраненное значение First Time на диске равно 1, это означает, что вы будете пойманы с помощью оператора if выше, поэтому внутри него вы можете делать все, что хотите, например, удалять старые таблицы и воссоздавать их снова с новой формацией.

Опять не то, что блестяще, но решает дело!

Ответ 2

Этот подход основан на NSUserDefaults. Идея состоит в том, чтобы получить предыдущий номер версии приложения (если существует) из NSUserDefaults и сравнить его с текущей версией.

код выполняет дб обновить, если предыдущая версия приложения <, чем текущая версия, или если предыдущая версия nil. Это означает, что этот подход можно использовать, даже если приложение уже было опубликовано в AppStore. Он обновит базу данных до новой версии во время обновления приложения.

Это файл plist:

enter image description here

Существует массив, состоящий из номера версии и набора запросов sql для соответствующей версии обновления. Предположим, что предыдущая версия - 1.2, а фактическая версия - 1.4, код выполняет обновление только с версии 1.2 до 1.4. Если предыдущей версией является 1.3, а текущий 1.4, код выполняет обновление только с 1.3 до 1.4. Если предыдущая версия равна нулю, код выполняет обновление до 1,1, затем до 1,2, затем до 1,3 и, наконец, до 1,4.

NSString * const VERSION_KEY = @"version";

-(void)upgradeDatabaseIfRequired{
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    NSString *previousVersion=[defaults objectForKey:VERSION_KEY];
    NSString *currentVersion=[self versionNumberString];

    if (previousVersion==nil || [previousVersion compare: currentVersion options: NSNumericSearch] == NSOrderedAscending) {
        // previous < current
        //read upgrade sqls from file
        NSString *plistPath = [[NSBundle mainBundle] pathForResource:@"UpgradeDatabase" ofType:@"plist"];
        NSArray *plist = [NSArray arrayWithContentsOfFile:plistPath];


        if (previousVersion==nil) {//perform all upgrades
            for (NSDictionary *dictionary in plist) {
                NSString *version=[dictionary objectForKey:@"version"];
                NSLog(@"Upgrading to v. %@", version);
                NSArray *sqlQueries=[dictionary objectForKey:@"sql"];
                while (![DB executeMultipleSql:sqlQueries]) {
                    NSLog(@"Failed to upgrade database to v. %@, Retrying...", version);
                };
            }
        }else{
            for (NSDictionary *dictionary in plist) {
                NSString *version=[dictionary objectForKey:@"version"];
                if ([previousVersion compare: version options: NSNumericSearch] == NSOrderedAscending) {
                    //previous < version
                    NSLog(@"Upgrading to v. %@", version);
                    NSArray *sqlQueries=[dictionary objectForKey:@"sql"];
                    while (![DB executeMultipleSql:sqlQueries]) {
                        NSLog(@"Failed to upgrade database to v. %@, Retrying...", version);
                    };
                }

            }
        }

        [defaults setObject:currentVersion forKey:VERSION_KEY];
        [defaults synchronize];
    }

}


- (NSString *)versionNumberString {
    NSDictionary *infoDictionary = [[NSBundle mainBundle] infoDictionary];
    NSString *majorVersion = [infoDictionary objectForKey:@"CFBundleShortVersionString"];
    return majorVersion;
}

Ответ 3

Вы также можете использовать .plist:

- (void)isItTheFirstTimeAfterUpdate {
    NSString *versionnum;
    NSError *error;
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
                                                         NSUserDomainMask,
                                                         YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    NSString *path = [documentsDirectory stringByAppendingPathComponent:@"yourplist.plist"];
    NSFileManager *fileManager = [NSFileManager defaultManager];

    if(![fileManager fileExistsAtPath:path]) {
        NSString *bundle = [[NSBundle mainBundle] pathForResource:@"yourplist" ofType:@"plist"];
        [fileManager copyItemAtPath:bundle toPath:path error:&error];
    }

    NSMutableDictionary *savedStock = [[NSMutableDictionary alloc] initWithContentsOfFile:path];
    versionnum = @"";
    //it can be installed by user (for ex. it is 1.3 but first installed), no plist value is set before
    if(([savedStock objectForKey:@"versionnum"]) && (![[savedStock objectForKey:@"versionnum"] isEqualToString:@""])){
        versionnum = [savedStock objectForKey:@"versionnum"];
    }

    //to get the version of installed/updated-current app
    NSString *myversion = [NSString stringWithFormat:@"%@",[[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"]];
    //if no version has been set-first install- or my version is the latest version no need to do sth.
    if ([versionnum isEqualToString:myversion] || [versionnum isEqualToString:@""]) {
        NSLog(@"Nothing has to be done");
    }
    else {
        [self cleanDB];//i have clean tables and create my new db tables maybe logout the user etc.
        [savedStock setObject:[NSString stringWithString:myversion] forKey:@"versionnum"];//setting the new version
        [savedStock writeToFile:path atomically:YES];
    }
}

И вы можете вызвать функцию в запуске приложения или в контроллере представления вашего главного контроллера. ваш выбор.

надеюсь, что это поможет.