2012-06-20 6 views
10

Ho un'app che utilizza MagicalRecord e sto pre-compilando il database con una grande quantità di dati che viene utilizzata come riferimento. All'interno dello stesso modello di dati, ho informazioni definibili dall'utente relative alle cose che l'utente può fare nell'app.MagicalRecord: più database

L'app è stata rifiutata perché i dati pre-compilati dovrebbero essere contrassegnati come "non eseguire il backup". Quindi, mi piacerebbe avere quei dati in un datastore separato in modo che io possa mantenere i dati dell'utente come backup.

C'è un modo per avere due datastore separati utilizzando MagicalRecord?

risposta

15

Penso che sia possibile, ma non troppo facile però. Come sapete, per lavorare con più di un database, dovreste apportare alcune modifiche al vostro PersistentStoreCoordinator, quindi avrà due PersistentStores. Dopo questo, lo stack dei dati principali sarà simile al seguente: enter image description here

L'altro modo è due due PersistentStoreCoordinator separati, ognuno con un solo archivio.

nella magica Record, ci sono diversi metodi di classe per l'aggiunta di negozi in NSPersistentStoreCoordinator + MagicalRecord.h.

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

credo, che questo è il posto dove si poteva fare la cosa che si desidera.

Inoltre vorrei ricordare, che tutta la proccess di impostare lo stack va in MagicalRecord + Setup.h

+ (void) setupCoreDataStackWithStoreNamed:(NSString *)storeName 

modo da poter aggiungere le vostre Negozi e Coordinatori lì. Non l'ho mai gestito da solo, era solo una breve indagine su una possibile soluzione.

6

Sono stato in grado di risolvere questo problema utilizzando le configurazioni. Dal momento che il Magical Record invia sempre null per il parametro di configurazione, sono andato a pezzi setupCoreDataStackWithAutoMigratingSqliteStoreNamed e sostituito con un metodo che supporta più configurazioni.

Poiché il Magical Record fa un buon lavoro di gestione delle migrazioni automatiche, prima chiamo il numero setupCoreDataStackWithAutoMigratingSqliteStoreNamed, seguito da cleanup, quindi fornisco il mio codice sostitutivo.

Ho un modello a oggetti con i miei oggetti seme dati assegnati alla configurazione "Seed" e agli oggetti utente assegnati alla configurazione "Utente". Magical Record è già stato inizializzato in modo da poter eseguire automaticamente la migrazione, se necessario.

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

Inoltre, MR 3.0 ha stack simultanei che possono risolvere il problema una volta eseguito.

+0

Ciao @Ron, quale negozio passi a setupCoreDataStackWithAutoMigratingSqliteStoreNamed come ne hai due? Quello senza seme? – DAN

0

Mantenere i dati per diverse entità Core Data in diversi file di archivio è ben supportato e abbastanza semplice. Tuttavia, MagicalRecrd non fornisce alcun metodo pratico per configurare lo stack di dati principali in questo modo. Devi semplicemente allocare lo stack manualmente e dire a MagicalRecord di usare lo NSPersistentStoreCoordinator che hai creato. Ecco come ho fatto in rapida:

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) ") 
     } 
    } 
} 

Si noti che nel mio codice mi riferisco al concetto di negozio "seme", come "contenuto" e il negozio definibile dall'utente come "utente".

Per realizzare il secondo aspetto della domanda, configurare il Content Store in modo che non venga eseguito il backup, è sufficiente giocare con gli URL in cui è archiviato ogni negozio, collocando il Content Store in una directory temporanea senza backup. e copiandolo in quella posizione fino all'avvio dal pacchetto di app se non esiste.

Problemi correlati