MagicalRecord:多个数据库

时间:2012-06-20 16:21:43

标签: ios core-data magicalrecord

我有一个使用MagicalRecord的应用程序,我使用大量用于参考的数据预先填充数据库。在同一个数据模型中,我有用户可定义的信息,这些信息与用户可能在应用程序中执行的操作有关。

该应用被拒绝,因为预先填充的数据应该标记为“不备份”。所以,我想将这些数据放在一个单独的数据存储区中,以便我可以将用户数据保持为可备份数据。

有没有办法使用MagicalRecord拥有两个独立的数据存储区?

3 个答案:

答案 0 :(得分:15)

我认为这是可能的,但不是太容易。 如您所知,要使用多个数据库,您应该对PersistentStoreCoordinator进行一些更改,因此它会有两个PersistentStores。在此之后,您的Core Data堆栈将如下所示: enter image description here

另一种方式是两个制作两个独立的PersistentStoreCoordinator,每个都携带一个商店。

在Magical Record中,有几种用于添加商店的类方法 的 NSPersistentStoreCoordinator + MagicalRecord.h 即可。

  
      
  • (NSPersistentStore *)MR_addInMemoryStore;
  •   
  • (NSPersistentStore *)MR_addAutoMigratingSqliteStoreNamed:(NSString *)storeFileName;
  •   
  • (NSPersistentStore *)MR_addSqliteStoreNamed:(id)storeFileName withOptions:(__ autoreleasing NSDictionary *)options;
  •   

我认为,这是你可以做你想做的事情的地方。

另外我应该提一下,设置堆栈的整个过程都在 MagicalRecord + Setup.h

+ (void) setupCoreDataStackWithStoreNamed:(NSString *)storeName

所以你可以在那里添加你的商店和协调员。 我自己从未管理过,这只是对可能解决方案的简要调查。

答案 1 :(得分:6)

我能够使用配置解决此问题。由于Magical Record总是为配置参数发送null,因此我将setupCoreDataStackWithAutoMigratingSqliteStoreNamed拆开并用支持多种配置的方法替换它。

由于Magical Record在处理自动迁移方面做得很好,我首先调用setupCoreDataStackWithAutoMigratingSqliteStoreNamed,然后进行清理,然后提供替换代码。

我有一个对象模型,我的种子数据对象分配了"种子"配置和用户对象分配给"用户"组态。 Magical Record已经初始化,因此可以在必要时自动迁移。

+(void) RB_setupMultipleStores:(NSString *) seedStoreName userStore:(NSString *) userStoreName
/* change persistent store to one with multiple configurations. Assumes Magical Record is initialized. */
{
NSError * error= nil;

[MagicalRecord cleanUp];

NSManagedObjectModel * model = [NSManagedObjectModel MR_defaultManagedObjectModel];

NSURL *seedURL = [NSPersistentStore MR_urlForStoreName:[seedStoreName stringByAppendingString:@".sqlite"]];

NSPersistentStoreCoordinator * coordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:model];

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

NSPersistentStore * seedStore =[coordinator
                                  addPersistentStoreWithType:NSSQLiteStoreType
                                  configuration:@"Seed"
                                  URL:seedURL
                                  options:options
                                  error:&error];
if (!seedStore || error)
{
    NSLog(@"Error setting up seed store:%@ for %@", [error localizedDescription], seedURL);
    exit(-1);
}

NSURL *userURL = [NSPersistentStore MR_urlForStoreName:[userStoreName stringByAppendingString:@".sqlite"]];

NSPersistentStore * userStore = [coordinator
                                 addPersistentStoreWithType:NSSQLiteStoreType
                                 configuration:@"User"
                                 URL:userURL
                                 options:options
                                 error:&error];

if (!userStore || error)
{
    NSLog(@"Error setting up user store:%@ for %@", [error localizedDescription], userURL);
    exit (-1);
}
[NSPersistentStoreCoordinator MR_setDefaultStoreCoordinator:coordinator];

[NSManagedObjectContext MR_initializeDefaultContextWithCoordinator:coordinator];
}

此外,MR 3.0具有并发堆栈,一旦完成就可以解决问题。

答案 2 :(得分:1)

将不同Core Data实体的数据保存在不同的商店文件中得到了很好的支持,并且相当简单。但是,MagicalRecrd不提供以这种方式设置Core Data堆栈的任何便利方法。您只需手动分配堆栈,并告诉MagicalRecord使用您创建的NSPersistentStoreCoordinator。以下是我在swift中的表现:

import Foundation
import CoreData
import MagicalRecord

class CoreDataSetup {
    static func setupAutoMigratingStack(withContentConfigurationName contentConfigurationName: String, userConfirgurationNameName: String) {
        MagicalRecord.cleanUp()

        let managedObjectModel = NSManagedObjectModel.MR_defaultManagedObjectModel()
        let persistentStoreCoordinator = NSPersistentStoreCoordinator(managedObjectModel: managedObjectModel!)

        let contentURL = NSPersistentStore.MR_urlForStoreName(contentConfigurationName + ".sqlite")
        let userURL = NSPersistentStore.MR_urlForStoreName(userConfirgurationNameName + ".sqlite")
        let options = [
            NSMigratePersistentStoresAutomaticallyOption : true,
            NSInferMappingModelAutomaticallyOption: true,
            NSSQLitePragmasOption: ["journal_mode": "DELETE"]
        ]
        do {
            try persistentStoreCoordinator.addPersistentStoreWithType(NSSQLiteStoreType, configuration: contentConfigurationName, URL: contentURL, options: options)
            try persistentStoreCoordinator.addPersistentStoreWithType(NSSQLiteStoreType, configuration: userConfirgurationNameName, URL: userURL, options: options)

            NSPersistentStoreCoordinator.MR_setDefaultStoreCoordinator(persistentStoreCoordinator)
            NSManagedObjectContext.MR_initializeDefaultContextWithCoordinator(persistentStoreCoordinator)
        } catch {
            print("Error adding persistent store to coordinator: \(error) ")
        }
    }
}

请注意,在我的代码中,我将“种子”商店的概念称为“内容”,将用户可定义的商店称为“用户”。

要完成问题的第二个方面,将内容存储配置为不备份,您只需要使用存储每个商店的URL,将内容存储库放在非备份的临时目录中,如果它不存在,则将其从您的应用包中复制到该位置。