我有一个使用MagicalRecord的应用程序,我使用大量用于参考的数据预先填充数据库。在同一个数据模型中,我有用户可定义的信息,这些信息与用户可能在应用程序中执行的操作有关。
该应用被拒绝,因为预先填充的数据应该标记为“不备份”。所以,我想将这些数据放在一个单独的数据存储区中,以便我可以将用户数据保持为可备份数据。
有没有办法使用MagicalRecord拥有两个独立的数据存储区?
答案 0 :(得分:15)
我认为这是可能的,但不是太容易。
如您所知,要使用多个数据库,您应该对PersistentStoreCoordinator
进行一些更改,因此它会有两个PersistentStores
。在此之后,您的Core Data堆栈将如下所示:
另一种方式是两个制作两个独立的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,将内容存储库放在非备份的临时目录中,如果它不存在,则将其从您的应用包中复制到该位置。