在iPhone上的Appstore上更改应用程序版本时,sqlite数据库更新

时间:2012-01-09 20:01:05

标签: iphone ios xcode sqlite app-store

我在app store上有一个版本1.0的应用程序,它使用sqlite数据库来读取数据。
现在我想用数据库文件中的更新将我的版本更新为1.1。使用开发人员证书时我在设备上安装app并没有更新数据库,因为数据库文件已经存在于文件夹中,所以我必须手动删除应用程序并重新安装。
我的问题是,当任何用户更新应用程序时,数据库也会根据当前版本进行更新。
欢迎提出任何建议。
谢谢

3 个答案:

答案 0 :(得分:15)

我确信有很多方法可以做到这一点(并且有很多方法比我的更好),但我处理这些问题的方式如下:

首先,我在应用程序的第一个.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

由于光盘上保存的第一时间值为1,这意味着您将被上面的if语句捕获,因此在其中您可以执行任何您想要的操作,例如删除旧表并使用新编队重新创建它们。

再一次不那么精彩,但解决了这个问题!

答案 1 :(得分:12)

这种方法依赖NSUserDefaults。我们的想法是从NSUserDefaults获取以前的应用版本号(如果存在),并将其与当前版本进行比较。

如果之前的应用版本<比当前版本或先前版本为nil,则代码执行db upgrade。这意味着即使应用程序已在AppStore上发布,也可以使用此方法。它将在应用更新期间将数据库升级到新版本。

这是一个plist文件:

enter image description here

有一个数组由版本号和一组用于相应升级版本的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;
}

答案 2 :(得分:6)

您也可以使用.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];
    }
}

您可以在应用程序启动时或在主视图控制器的视图控制器中调用该函数。您的选择。

希望它有所帮助。