如何在iPhone应用更新上更新SQLite DB?

时间:2010-05-04 18:13:31

标签: iphone objective-c sqlite

我目前在iTunes应用商店中有一个使用SQLite数据库作为数据存储区的iPhone应用。用户可以将应用程序与Web服务同步,然后将返回的数据存储在SQLite数据库中。用户还可以将新项目插入数据库,并将其更改同步回Web服务。

当连接打开到应用程序的本地数据库时,代码会检查以确认数据库文件是否存在于“Documents”文件夹中,如果数据库文件不是通过从“Resources”文件夹复制到“文件”文件夹。

我必须发布应用程序的更新。此更新包含数据库架构更改(新表,列等)。根据我的阅读,“Documents”目录中的文件将保留在应用程序更新中,这意味着更新后现有数据库仍然完好无损。

我的问题是,如何用我更新的数据库替换现有数据库,有没有办法在不丢失现有数据库中的数据的情况下这样做?是否存在某种“更新后首次运行”事件,我可以使用它来执行数据库更新,或者我是否必须对现有数据库进行某种检查(查找新列或表)以及检查是否失败手动更换/更新数据库?

谢谢!

3 个答案:

答案 0 :(得分:17)

您应该将应用程序的当前版本号存储在某个地方 - 在数据库中或更好地存储在默认数据库中。启动时,您的应用会将其自己的版本号与持久版本号进行比较。如果它们不同,则这是更新后的第一次运行。如果不存在持久版本号,那么显然这也是更新后的第一次运行。

至于更新数据库,如果它已经到位,您将使用通常的SQL ALTER命令来更新模式,并同时进行任何数据库数据迁移。

答案 1 :(得分:4)

sqlite3 *数据库;     sqlite3_stmt * update_statement = nil;

if(sqlite3_open([strDatabasePath UTF8String], &database) == SQLITE_OK)
{
   nsstring  *strMQueryupdate="write your query here";

    const char *sql = [strMQueryupdate UTF8String];

    if (sqlite3_prepare_v2(database, sql, -1, &update_statement, NULL) != SQLITE_OK) {
        NSLog(@"update fails");
    }
    else
    {
        sqlite3_bind_text(update_statement, 1, [[arrayname objectAtIndex:0]  UTF8String], -1, SQLITE_TRANSIENT);


        int success = sqlite3_step(update_statement);
        sqlite3_reset(update_statement);
        if (success == SQLITE_ERROR){}
        else {}
    }
    sqlite3_finalize(update_statement);
}
sqlite3_close(database);   

答案 2 :(得分:3)

我们通过在服务器中查询通过查询服务器数据库的php文件吐出的plist标头中的哈希值来检查更新。您可以在本地存储该哈希,并将其与应用程序上次运行时进行比较。这样手机就知道它的版本是否过时了。然后我们在后台下载新的plist并在手机上更新数据库。

编辑:

在我们的php结束时,我们得到了一个MD5,它是我们在服务器上生成的plist的XML输出,如下所示:

header("MD5-Hash: ". md5($xml_output));
echo $xml_output;

然后我们从userDefaults获取iPhone上的plist哈希值,如下所示:

NSUserDefaults* defaults  = [NSUserDefaults standardUserDefaults];
curHash = [defaults stringForKey:kUpdateUserDefault];

来自NSURLRequest的服务器哈希,如下所示:

NSString *hash = [[[res allHeaderFields] objectForKey:kUpdateHeaderField] retain];

然后我们比较两者并仅在散列不匹配时开始下载:

    if (![curHash isEqualToString:hash]) {
            [self performSelector:@selector(sendUpdateStarted) onThread:[NSThread mainThread] withObject:nil waitUntilDone:NO];
            ... download the file and save it as the new iPhone's plist
    }

此代码由我非常有能力的合作伙伴Oliver Rice撰写。

相关问题