10

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

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

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

4

3 回答 3

15

我认为这是可能的,但不是太容易。如您所知,要使用多个数据库,您应该对您PersistentStoreCoordinatorPersistentStores. 在此之后,您的核心数据堆栈将如下所示: 在此处输入图像描述

另一种方式是两个创建两个独立的 PersistentStoreCoordinators,每个承载一个存储。

在 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

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

于 2012-06-20T19:11:32.190 回答
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 具有并发堆栈,一旦完成就可以解决问题。

于 2014-06-03T19:04:51.710 回答
2

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

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,将内容存储放置在未备份的临时目录中,然后复制它如果它不存在,则从您的应用程序包启动到该位置。

于 2016-03-10T20:05:09.230 回答