iPhone App Store更新系统,以及对数据库的影响

时间:2010-11-10 13:45:14

标签: iphone sqlite

许多人,我必须在模拟器中删除我的应用程序才能重新安装一个新版本,我将更新我的数据库。否则,它会在有或没有调试日志的情况下崩溃(如果它是核心数据,则调试日志非常自我解释)。

我的问题是:由于用户在通过应用商店进行更新之前不会删除他们的应用,因为他们在升级后肯定会想要他们的“旧”数据,

我们是否必须在每次发布时开发数据库迁移脚本,或者在数据库发生变化时签入applicationDidLaunch?

谢谢!

2 个答案:

答案 0 :(得分:3)

如果我的数据在更新后丢失,我肯定会给你1星 核心数据版本控制和迁移在几分钟内完成,至少是轻量级部分。

将此answer看作类似的问题

答案 1 :(得分:1)

我没有亲自使用过CoreData,所以不知道它是否有专门的工具来处理它。但是,通常是的,您需要创建和存储将从应用程序的每个版本迁移到下一个版本的SQL脚本。

安装应用程序后,应根据应用程序使用的数据模型版本检查数据模型的当前版本。应该有一个“delta”脚本从每个版本移动到每个下一个版本。然后应该应用从当前模型移动到必要模型所需的每个增量。

例如,如果您已向AppStore提交了4个版本。您需要增量脚本才能从版本1到2,从2到3以及从3到4。

每次启动应用程序时,它都会根据可执行文件所需版本检查数据模型的当前版本。例如,如果在设备上安装了版本4,但用户从未安装过版本3,则应用程序将启动。检查模型的当前版本,即2.将其与可执行文件的版本进行比较4.然后应用2到3脚本,然后应用3到4脚本。

版本号本身可以存储在数据库中,应该在应用增量之后递增,无论是从增量本身还是在处理代码中自动增加。

增量可以作为常量字符串存储在代码文件中,也可以作为项目中的资源文件存储。

编辑:(这是我的迁移代码)

+ (NSArray*) chop:(NSString*)sql {
    NSMutableArray* list = [[NSMutableArray alloc] init];
    NSMutableString* sb = [[NSMutableString alloc] init];
    BOOL inside = FALSE;

    for (int i=0;i<[sql length];i++) {
        if ([sql characterAtIndex:i] == '\n') continue;
        if ([sql characterAtIndex:i] == '\r') continue;

        [sb appendFormat:@"%c",[sql characterAtIndex:i]];
        if (!inside) {
            if ([sql characterAtIndex:i] == '\'')
                inside = TRUE;
            else if ([sql characterAtIndex:i] == ';') {
                [sb deleteCharactersInRange:NSMakeRange([sb length]-1,1)];
                [list addObject:sb];
                [sb release];
                sb = [[NSMutableString alloc] init];
            }
        } else {
            if ([sql characterAtIndex:i] == '\'')
                inside = FALSE;
            else if ([sql characterAtIndex:i] == '\\') {
                i++;
                [sb appendFormat:@"%c",[sql characterAtIndex:i]];
            }
        }
    }
    [sb release];
    return [list autorelease];
}

+ (void) updateObjectModel {
    [Log output:@"[migration]"];

    int version;
    @try {
        int exist = [SQL queryLong:@"SELECT COUNT(*) FROM Variables WHERE Key='objectModelVersion'"];
        if (exist)
            version = [SQL retrieveInt:@"objectModelVersion"]+1;
        else {
            [Log output:@"[bootstrapping]"];
            [SQL storeInt:@"objectModelVersion" as:1];
            version = 2;
        }
    } @catch (NSException* e) {
        [Log output:@"[initializing]"];
        version = 0;
    }

    while (TRUE) {
        NSString* filename = [NSString stringWithFormat:@"SQLite-%04d",version];
        NSString* file = [[NSBundle mainBundle] pathForResource:filename ofType:@"sql"];
        if (file) {
            [Log output:[NSString stringWithFormat:@"[%d]",version]];
            NSArray* commands = [SQL chop:[NSString stringWithContentsOfFile:file encoding:NSASCIIStringEncoding error:NULL]];
            for (NSString* command in commands)
                [SQL update:command];
            [SQL storeInt:@"objectModelVersion" as:version];
        } else break;

        version++;
    }
    [Log output:@"[/migration]\n"];
}