5

在我的应用程序中,我使用了 sqlite DB。我将应用程序的 1.0 版本提交到应用商店。但在那之后,我对数据库进行了一些更改,例如插入一些新行。

然后提交了1.1版本的app。But i will not able to get updated DB because the old DB already exists in device.

我该如何解决这个问题?

如果我删除应用程序然后安装新版本的应用程序,那么我得到了更新的数据库。

//My code for copy of DB is as follow:

- (void)createEditableCopyOfDatabaseIfNeeded
{
    // First, test for existence.
    BOOL success;
    NSFileManager *fileManager = [NSFileManager defaultManager];
    NSError *error;
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    NSString *writableDBPath = [documentsDirectory stringByAppendingPathComponent:@"xxx.sqlite"];
    success = [fileManager fileExistsAtPath:writableDBPath];
    if (success) return;

    // The writable database does not exist, so copy the default to the appropriate location.

    NSString *defaultDBPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"xxx.sqlite"];
    success = [fileManager copyItemAtPath:defaultDBPath toPath:writableDBPath error:&error];
    if (!success) {
        NSAssert1(0, @"Failed to create writable database file with message '%@'.", [error localizedDescription]);
    }
}

我在 appDidFinishLaunching 方法中调用了这个方法。

当新版本可用时,如何在不删除应用程序的情况下获取更新的数据库

4

3 回答 3

6

您可以使用NSUserDefaults来执行此操作。

在您的新版本中添加以下代码:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
  if(![[NSUserDefaults standardUserDefaults] boolForKey:@"1.1"]])
  {
     [self removeDatabase];
     [self createEditableCopyOfDatabaseIfNeeded];
     [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"1.1"];
  }
  //Other stuffs
}

删除旧数据库文件的方法:

- (void)removeDatabase
{
    BOOL success;
    NSFileManager *fileManager = [NSFileManager defaultManager];
    NSError *error;
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    NSString *removeDBPath = [documentsDirectory stringByAppendingPathComponent:@"xxx.sqlite"];
    success = [fileManager fileExistsAtPath:writableDBPath];
    if(success)
    {
       [fileManager removeItemAtPath:writableDBPath error:&error]
    }
}
于 2013-05-02T10:07:36.213 回答
0

您将需要执行数据库迁移,以便您的应用程序的老用户不会丢失他们的数据。

这意味着检查哪个版本的数据库已经存在,并执行必要的 SQL 语句来更新模式和数据。

MTMigration框架(MIT 许可)可以帮助您在每个版本的应用程序执行一次代码,例如:

[MTMigration migrateToVersion:@"1.1" block:^{
    // migrate the SQL database here
}];

但是您可能希望以不同的方式检测数据库的版本。

为这个过程编写一些单元测试是个好主意。搞砸用户数据是您最不想做的事情。

于 2013-05-02T09:02:31.720 回答
0

您必须编写数据迁移脚本:-

如果您需要对包含一些数据的现有表进行更改,则需要执行以下步骤:

1)重命名现有表

说 TableName 是“TestTable”,所以将表重命名为“TestTableOld”

2)创建一个名为“TestTable”的新表,其中包含您想要的新列和其他争吵。

3) 使用如下查询将数据从“TestTableOld”复制到“TestTable”:

插入 TestTable('col1',col2'...'coln') 值 Select col1, col2, col3,...'coln' From TestTableOld;

并且新添加的列设置值为空白,至于新条目将照此使用。

4)删除表'TestTableOld'

遵循上述四步过程,因为这将作为一个 alter 语句工作,并且它将保留原始表中的所有数据。

如果您使用的是 User_Version,那么将有助于用新数据库识别旧数据库

于 2013-05-02T10:14:45.743 回答