当 iPhone 的 Appstore 上的应用程序版本更改时,sqlite 数据库更新
Posted
技术标签:
【中文标题】当 iPhone 的 Appstore 上的应用程序版本更改时,sqlite 数据库更新【英文标题】:sqlite database update when app version changes on Appstore in iPhone 【发布时间】:2015-06-24 14:40:58 【问题描述】:我在应用商店有一个版本为 1.0 的应用,它使用 sqlite 数据库读取数据。现在我想通过更新数据库文件将我的版本更新到 1.1。在安装时使用开发人员证书设备上的应用程序它没有更新数据库,因为数据库文件已经存在于文档文件夹中,所以我必须手动删除应用程序并重新安装它。我的问题是,当任何用户更新应用程序时,数据库也会得到根据当前版本更新。欢迎提出任何建议。谢谢
【问题讨论】:
数据是只读的还是读/写的? 【参考方案1】:我确信有很多方法可以做到这一点(还有很多比我的更好的方法),但我处理此类问题的方式如下:
首先,我在应用程序的第一个 .h 文件(将首先加载的文件)中定义一个常量来指示首次加载并将其设置为 0:
#define FirstTime 0
现在您必须知道我打算将此常量的值保存在 Documents 文件夹中以供将来参考,因此我使用共享数据实例。在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】:您也可以使用.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];
您可以在应用程序启动或主视图控制器的视图控制器中调用该函数.. 您的选择。
希望对你有帮助。
【讨论】:
【参考方案3】:这种方法依赖于NSUserDefaults
。我们的想法是从NSUserDefaults
获取以前的应用版本号(如果存在)并将其与当前版本进行比较。
如果以前的应用程序版本<
高于当前版本或以前的版本为nil
,则代码执行数据库升级。这意味着即使应用程序已经在 AppStore 上发布,也可以使用这种方法。它会在应用更新期间将数据库升级到新版本。
这是一个 plist 文件:
有一个数组,由版本号和对应升级版本的一组sql查询组成。 假设以前的版本是 1.2,实际版本是 1.4,代码只执行从 1.2 到 1.4 的升级。如果以前的版本是 1.3,而当前的版本是 1.4,则代码只执行从 1.3 到 1.4 的升级。 如果之前的版本为 nil,则代码执行升级到 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;
【讨论】:
以上是关于当 iPhone 的 Appstore 上的应用程序版本更改时,sqlite 数据库更新的主要内容,如果未能解决你的问题,请参考以下文章
从 iPhone 应用程序链接 appStore 中的开发人员页面
iPad App Store 链接未显示 iPhone 应用程序