iOS核心数据对象模型在生产应用程序中的变化

时间:2012-11-29 16:02:08

标签: iphone ios database sqlite core-data

我现在有一个正在使用的应用程序。我对此应用的核心数据模型的下一个版本进行了重大更改。

为了避免从旧数据模型到新数据模型的大量转换工作,我只是简单地重命名了新的对象模型和数据库,从而导致新版本的应用程序不再引用旧数据库(这不是一个问题,因为旧的数据库数据很小,而且不需要)。

然而,我需要从旧数据库中获取一个数据,我不想让用户需要手动将其重新输入到新数据库中。

我的问题: 有什么方法可以将这些数据放入新数据库?

我可以针对sqlite数据库运行查询并直接进入新数据库吗?或者我是否需要创建一个完整的其他持久存储&对象模型拉数据?

还是我一起错过了什么?

3 个答案:

答案 0 :(得分:1)

您似乎只需要在用户首次运行更新的应用程序时将数据复制到新数据库。那时你可能会清除旧的那个,所以它占用了空间。不确定需要什么更复杂的解决方案。似乎足够了。

答案 1 :(得分:1)

我同意,我认为您应该使用核心数据连接到旧数据库并提取数据然后将其移动到新数据库。完成后,您应该删除旧的数据库文件(注意我假设您将核心数据结果存储到SQLite中):

- (NSURL *)urlForDocumentsDirectoryWithFile:(NSString *)fileName {
    NSURL *docPath = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
    return [docPath URLByAppendingPathComponent:fileName];
}

- (void)deleteFileFromDocumentsIfExists:(NSString *)fileName {
    NSFileManager *fileManager = [NSFileManager defaultManager];
    NSError *error;
    NSURL *filePath = [self urlForDocumentsDirectoryWithFile:fileName];
    NSLog(@"Deleting file: %@", filePath.absoluteString);
    if ([fileManager fileExistsAtPath:[filePath path]])
    {
        BOOL success = [fileManager removeItemAtURL:filePath error:&error];
        if (!success) NSLog(@"Error: %@", [error localizedDescription]);
    }
}

删除代码:

[self deleteFileFromDocumentsIfExists:@"MyOldDatabaseName.sqlite"];

如果你曾经只使用过一次旧模型,我不会担心有2个对象模型。我可以看到在你的应用程序中使用“一次性”代码是浪费的地方,但即使跳过核心数据并手动查询仍然需要你拥有它。

另外,我有一个DataAccessManager单元,我将所有核心数据的荒谬初始化代码转储到所有内容中,这样我就可以轻松访问多个上下文,如果你担心的是你所写的那些都是你可能想要的把它移到一个可共享的单位。

答案 2 :(得分:0)

感谢上述两条建议。我最终使用以下内容来解决我的问题:

步骤:

  • 尝试连接旧的SQLite数据库。
  • 如果连接成功,请阅读记录。
  • 在托管对象上下文中创建新的托管对象。
  • 使用sql结果中的值填充托管对象中的值。
  • 坚持管理对象。
  • 删除旧数据库。
NSString *dbFilePath = [[self applicationDocumentsDirectoryString] stringByAppendingPathComponent:@"RPS.sqlite"];

sqlite3 *database;

if (sqlite3_open([dbFilePath UTF8String], &database)) {
    NSLog(@"sqlite3_open: failed");
} else {
    NSString *nsquery = [[NSString alloc] initWithFormat:@"SELECT * FROM ztable"];
    const char *query = [nsquery UTF8String];

    sqlite3_stmt *statement;
    int prepareCode = (sqlite3_prepare_v2( database, query, -1, &statement, NULL));
    if(prepareCode == SQLITE_OK) {
        MyTable *myTableRecord;
        NSLog(@"About to start adding the data");
        while (sqlite3_step(statement) == SQLITE_ROW)
        {
            NSLog(@"***************** row returned ******************");

            myObject = [NSEntityDescription insertNewObjectForEntityForName:@"myTable" inManagedObjectContext:self.managedObjectContext];

            [myTable setValue:[NSString stringWithFormat:@"%s",(char *)sqlite3_column_text(statement, 7)] forKey:@"field1"];
            [myTable setValue:[NSString stringWithFormat:@"%s",(char *)sqlite3_column_text(statement, 8)] forKey:@"field2"];

            [self saveContext];

        }

        sqlite3_finalize(statement);
        NSLog(@"Added sqlite3 data");
    } else {
        NSLog(@"Prepare code was not right: %d",prepareCode);
    }

    NSError *err;
    NSFileManager *filemgr = [[NSFileManager alloc] init];
    [filemgr removeItemAtPath:dbFilePath error:&err];
    NSLog(@"Deleted old sqlite3 database");
}