2012-06-20 24 views
10

Mam aplikację, która używa MagicalRecord, i wstępnie zapełniam bazę danych dużą ilością danych, która służy do odniesienia. W ramach tego samego modelu danych mam zdefiniowane przez użytkownika informacje dotyczące rzeczy, które użytkownik może wykonywać w aplikacji.MagicalRecord: wiele baz danych

Aplikacja została odrzucona, ponieważ wstępnie wypełnione dane mają być oznaczone jako "nie archiwizuj". Chciałbym mieć te dane w oddzielnym magazynie danych, aby zachować dane użytkowników jako kopie zapasowe.

Czy istnieje sposób na posiadanie dwóch oddzielnych datastores za pomocą MagicalRecord?

Odpowiedz

15

Myślę, że to możliwe, ale nie jest to łatwe. Jak wiesz, do pracy z więcej niż jedną bazą danych, powinieneś wprowadzić pewne zmiany do swojego PersistentStoreCoordinator, więc będzie miał dwa PersistentStores. Po tym stosie danych podstawowych będzie wyglądać następująco: enter image description here

Drugi sposób to dwa oddzielne PersistentStoreCoordinators, z których każdy ma jeden sklep.

magicznych Record, istnieje kilka metod klasy dodawania sklepów w NSPersistentStoreCoordinator + MagicalRecord.h.

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

myślę, że to jest miejsce, gdzie można zrobić coś chcesz.

Ponadto należy wspomnieć,, że cała proccess utworzenia stos idzie w MagicalRecord + Setup.h

+ (void) setupCoreDataStackWithStoreNamed:(NSString *)storeName 

Więc można dodać swoje sklepy i koordynatorów tam. Nigdy nie udało mi się tego samodzielnie, to było tylko krótkie śledztwo w sprawie możliwego rozwiązania.

6

Byłem w stanie rozwiązać ten problem za pomocą konfiguracji. Ponieważ Magical Record zawsze wysyła null dla parametru konfiguracyjnego, zerwałem setupCoreDataStackWithAutoMigratingSqliteStoreNamed i zastąpiłem go metodą obsługującą wiele konfiguracji.

Ponieważ Magical Record wykonuje dobrą robotę przy automatycznych migracjach, najpierw zadzwonię pod numer setupCoreDataStackWithAutoMigratingSqliteStoreNamed, a następnie wyczyszczę, a następnie dostarczę mój kod zastępczy.

Mam jeden model obiektowy z moimi obiektami danych początkowych przypisanymi do konfiguracji "Seed" i obiektami użytkowników przypisanymi do konfiguracji "User". Magical Record został już zainicjowany, aby w razie potrzeby automatycznie przeprowadzić migrację.

+(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]; 
} 

Również MR 3.0 ma równoczesne stosy, które mogą rozwiązać problem po jego zakończeniu.

+0

Witam @Ron, który sklep przechodzisz do setupCoreDataStackWithAutoMigratingSqliteStoreNazwa, jak masz dwa z nich? Ten bez nasion? – DAN

0

Przechowywanie danych dla różnych jednostek danych podstawowych w różnych plikach sklepów jest dobrze obsługiwane i dość proste. Jednak MagicalRecrd nie zapewnia żadnych wygodnych metod konfigurowania stosu danych podstawowych w ten sposób. Musisz po prostu przydzielić swój stos ręcznie i powiedzieć MagicalRecord, aby użyć utworzonego NSPersistentStoreCoordinator. Oto jak to zrobiłem w 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) ") 
     } 
    } 
} 

Należy zauważyć, że w moim kodu mam na myśli swojej koncepcji „nasion” sklep jako „zawartość” i sklepu użytkownika definiowane jako „użytkownik”.

Aby rozwiązać drugi aspekt pytania, nie trzeba konfigurować magazynu zawartości, aby można było tworzyć kopie zapasowe, wystarczy, że połączysz się z adresami URL, w których przechowujesz każdy ze sklepów, umieszczając magazyn treści w katalogu tymczasowym, którego kopia zapasowa nie zawiera kopii zapasowej. i skopiowanie do tej lokalizacji jest uruchamiane z pakietu aplikacji, jeśli nie istnieje.