2012-03-27 4 views
6

Background: Ho un oggetto gestito, Car. Ho una API di ricerca RESTful seduta su localhost/auto/ricerca. I risultati restituiti sono oggetti Car dal lato server, ma voglio solo salvare quello scelto dall'utente. Il resto delle macchine che voglio scartare quando toccheranno fuori dalla ricerca.Best practice per oggetti temporanei in RestKit con Core Data

All'inizio ero tutti come:

@interface Car : NSManagedObject //<--- managed object 

    @property (nonatomic, strong) NSNumber* year; 
    @property (nonatomic, strong) NSString* make; 
    @property (nonatomic, strong) NSString* model; 

@end 

@interface TransientCar : NSObject //<--- regular NSObject! 

    @property (nonatomic, strong) NSNumber* year; 
    @property (nonatomic, strong) NSString* make; 
    @property (nonatomic, strong) NSString* model; 

@end 

stavo mappatura della ricerca API REST risultati JSON in oggetti TransientCar ai fini della visualizzazione dei risultati di ricerca, ma non li risparmio al contesto. Per impostazione predefinita, se si esegue il mapping di un oggetto gestito, RestKit chiamerà il suo + oggetto factory di convenienza per creare l'oggetto e inserirlo nel contesto corrente (hardcoded per il contesto del negozio oggetti condiviso, btw!)

Questo sembrava insostenibile. Così ora sto usando solo NSMutableDictionary per contenere i dati dei risultati di ricerca fino a quando l'utente tocca in una vista di dettaglio e fa qualcosa vale la pena salvare un oggetto reale gestito per:

RKObjectMapping* tempCarMapping = [RKObjectMapping mappingForClass:[NSMutableDictionary class]]; 
[tempCarMapping mapKeyPathsToAttributes: 
@"year", @"year", 
@"make", @"make", 
@"model", @"model", 
nil]; 

Si tratta di una buona pratica? Usando NSMutableDictionary come rappresentazione temporanea fino a quando l'utente non fa qualcosa che garantisce l'inserimento di un nuovo oggetto nel contesto? Ero un po 'un fan dell'uso della sottoclasse dell'oggetto gestito originale per rappresentare i dati, ma in qualche modo di poterlo contrassegnare come "non tenere" o qualcosa del genere, ma ogni volta che lo faccio mi sento come se stessi combattendo il framework (e condizioni di gara). Ho anche provato ad utilizzare un graffio/contesto usa e getta con la creazione di un nuovo RKObjectManager e proprio di compensazione tutto il suo contesto in seguito, ma il metodo + managedObjectContext di di RestKit categoria ActiveRecord è hardcoded per tornare:

[[[RKObjectManager sharedManager] objectStore] managedObjectContext]; 

Quella sorta di scappa la possibilità di mai usare un contesto zero per i dati temp/trash.

risposta

3

In primo luogo, ho fatto questo in passato usando il tuo metodo di avere due copie del modello, una che è per Core Data e una che è transitoria (solo un NSObject). Ha funzionato senza problemi per me.

Per quanto riguarda gli altri tuoi tentativi, non credo che la biblioteca ti costringa a forzare la mano tanto quanto pensi. Guarda l'API per RKManagedObjectStore e NSManagedObject+ActiveRecord. In particolare, RKManagedObjectStore ha una proprietà managedObjectContext, un metodo - (NSManagedObjectContext*)newManagedObjectContext e diversi metodi per unire le modifiche.

Hai ragione che il numero [NSManagedObject managedObjectContext] restituisce sempre il contesto di sharedManager, ma questo ha senso, è un metodo di classe. Altrimenti come avrebbe la classe sapere quale contesto tornare? Ma è discutibile visto che ci sono tanti altri modi per creare nuovi contesti e accedervi. O evitandoti del tutto, potresti semplicemente mantenere un riferimento al tuo contesto temporaneo e utilizzarlo direttamente.

Questo ti dà alcune opzioni: avere più Object Manager, avere un gestore oggetti ma creare un contesto temporaneo da esso e mantenere solo gli oggetti che vuoi, creare un oggetto temporaneo basato sull'oggetto gestito.

L'opzione NSMutableDictionary non sembra flessibile come gli altri metodi, ma non direi che è "cattiva pratica".

+0

Avere una classe di modello transitoria che eredita solo da NSObject va bene, ma la mia più grande preoccupazione è mantenere il modello transitorio aggiornato con la versione NSManagedObject. È più un problema di manutenibilità del codice che tecnico. Sarebbe bello che la sottoclasse Editor> Genera NSManagedObject avesse una casella di controllo per "con sottoclasse NSObject con mirroring". –

+0

Certamente - e se il tuo modello cambierà con qualsiasi frequenza, uno degli altri metodi che ho delineato sarebbe una buona scelta. –

5

Sfortunatamente, non ho ancora abbastanza reputazione StackOverflow per inserire questa risposta a cui appartiene (come commenti alle altre risposte), ma volevo aggiungere alcuni punti.

Credo che la risposta di Evan Cordell sia difettosa. La versione corrente del restkit (0.10.x) non consente di creare contesti per RKManagedObjectLoaders da utilizzare e RKObjectManagers può prendere un archivio, ma deve essere di tipo RKManagedObjectStore, che è esplicitamente legato a sqllite. A quanto pare, la versione di dev del restkit (0.20) lo rilassa, quindi puoi salvarlo su un database in memoria. Ho provato a sovrascrivere i metodi RKManagedObjectStore per utilizzare un contesto che ho fornito, ma non ha funzionato ... in ogni caso, la correzione sembra non banale.

L'altro collegamento fornito, Better Approach for Creating Temp Object for Core Data with Restkit, sembra fare con la pubblicazione di un oggetto e la ricezione dello stesso oggetto nella risposta. È un problema diverso da quello che è stato posto in questa domanda.

Fino a quando non verrà rilasciata v.0.20.x, che si spera sia presto, sembra che una gerarchia di classi parallele sia l'unica scelta. Se non sono corretto, accolgo con favore la correzione su questo punto!

+0

RestKit cambia frequentemente e il modo migliore per capire cosa supporta è controllare i documenti. Tuttavia, non dovrebbe cambiare molto dopo 1,0. In questo momento c'è un modo per creare un RKManagedObjectStore con qualsiasi coordinatore di negozio permanente e per aggiungere/rimuovere contesti a volontà. –