У меня есть приложение с версией 1.0 в хранилище приложений, которое использует базу данных sqlite для чтения данных.
Теперь я хочу обновить мою версию до версии 1.1 с обновлением в файле базы данных.
При использовании сертификата разработчика, когда Я устанавливаю приложение на устройство, которое не обновляло базу данных, поскольку файл базы данных уже существует в папке с документами, поэтому мне нужно вручную удалить приложение и установить его снова.
Мой вопрос: когда пользователь обновляет приложение, База данных также обновляется в соответствии с текущей версией.
Любые предложения приветствуются.
Спасибо
Обновление базы данных sqlite при изменении версии приложения на Appstore в iPhone
Ответ 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:
Существует массив, состоящий из номера версии и набора запросов 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];
}
}
И вы можете вызвать функцию в запуске приложения или в контроллере представления вашего главного контроллера. ваш выбор.
надеюсь, что это поможет.