使用RestKit进行轻量级迁移

时间:2012-07-31 08:06:41

标签: cocoa-touch ios5 core-data migration restkit

Apple的文档提供了以下用于设置(自动)轻量级迁移的示例:

NSError *error = nil;
NSURL *storeURL = <#The URL of a persistent store#>;
NSPersistentStoreCoordinator *psc = <#The coordinator#>;
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
    [NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
    [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];

BOOL success = [psc addPersistentStoreWithType:<#Store type#>
                    configuration:<#Configuration or nil#> URL:storeURL
                    options:options error:&error];
if (!success) {
    // Handle the error.
}

但是我使用RestKit,它负责在幕后创建持久性存储。我的初始化代码的简化版本如下所示:

// Initialize RestKit
RKObjectManager* objectManager = [RKObjectManager objectManagerWithBaseURL:rootURL];

// Create the object store
objectManager.objectStore = [RKManagedObjectStore objectStoreWithStoreFilename:databaseName                 
                                                                 usingSeedDatabaseName:seedDatabaseName 
                                                                    managedObjectModel:nil //Don't need to pass it in. It is infered  
                                                                          delegate:self];
// Create Mappings
...

// Define Relationships
...

// Set Mappings
...

鉴于RestKit在幕后创建了persistantStore,我应该在哪里传递配置选项?

2 个答案:

答案 0 :(得分:2)

在我的理解中,RestKit位于Core Data之上。因此,即使您使用种子数据库并让RestKit为对象管理器分配对象存储,也将使用Core Data提供的sqlite数据库。

要使用RestKit启用轻量级迁移,您可以在AppDelegate中使用- (NSPersistentStoreCoordinator *)persistentStoreCoordinator方法(请参阅此thread

AppDelegate

- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
    if (__persistentStoreCoordinator != nil) return __persistentStoreCoordinator;

    NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"thenameofyoursqlite.sqlite"];

    NSError *error = nil;
    __persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];

    NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
    [NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
    [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];

    if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:options error:&error])
    {
        NSLog(@"Auto migration failed, error %@, %@", error, error.userInfo);
        abort();
    }
}

答案 1 :(得分:2)

您可以在RKManagedObjectStore.m方法的createPersistentStoreCoordinator中添加这些选项。

对于RestKit的0.10版本,它已经添加,不确定是否为最新版本。但如果还没有添加,你可以自己添加。该方法的最终外观将是这样的。

- (void)createPersistentStoreCoordinator
{
    NSAssert(_managedObjectModel, @"Cannot create persistent store coordinator without a managed object model");
    NSAssert(!_persistentStoreCoordinator, @"Cannot create persistent store coordinator: one already exists.");
    NSURL *storeURL = [NSURL fileURLWithPath:self.pathToStoreFile];

    NSError *error;
    _persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:_managedObjectModel];

    // Allow inferred migration from the original version of the application.
    NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
                             [NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
                             [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];

    if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:options error:&error]) {
        if (self.delegate != nil && [self.delegate respondsToSelector:@selector(managedObjectStore:didFailToCreatePersistentStoreCoordinatorWithError:)]) {
            [self.delegate managedObjectStore:self didFailToCreatePersistentStoreCoordinatorWithError:error];
        } else {
            NSAssert(NO, @"Managed object store failed to create persistent store coordinator: %@", error);
        }
    }
}

我已经在我的项目中测试了这个,通过添加3个新实体并重命名旧实体,并且在不删除设备之前的应用程序的情况下工作正常。 希望这会对你有所帮助。