9

Puh, Entschuldigung für den langen Titel.Speichern einzelner CoreData-Entität (nicht den gesamten Kontext), während NSFetchedResultController-Funktionalität beibehalten

Ich habe einen einzigen Managed Object Context, wo ich Songs von zwei verschiedenen Orten gespeichert speichern. Ich erhalte einige der Songs aus dem persistenten Speicher auf dem Telefon (mit Core Data), und ich ziehe einige der Songs aus einer Online-Datenbank. Beide Songs haben die gleiche MananagedObject-Unterklasse. Ich möchte, dass beide Songs in einem einzigen Kontext sind, weil ich möchte, dass sie beide in einer Tabellenansicht angezeigt werden, die mit einem NSFetchedResultsController verbunden ist.

Das Problem tritt auf, wenn ich einen der Songs speichern möchte. Ich möchte nicht alle Lieder speichern, die ich aus der Online-Datenbank auf das Telefon gezogen habe. Ich möchte nur das einzelne Lied speichern, also funktioniert ein einfaches [moc save] nicht. Das andere Problem ist, dass, nachdem ich den einzelnen Song gespeichert habe, ich immer noch möchte, dass die aus dem Internet gezogenen Songs im Kontext sind (aber wiederum nicht gespeichert werden). Ich glaube, ich habe ein paar verschiedene Optionen:

1) Ist es möglich, einen NSFetchedResults-Controller mit mehreren Kontexten verbunden zu haben?

2) Ich könnte alle Songs aus der Online-Datenbank in einen separaten temporären Kontext verschieben, im ursprünglichen Kontext speichern und dann alle Songs zurück verschieben. (siehe: How do I copy or move an NSManagedObject from one context to another?)

3) Merken Sie sich alle Schlüssel-Wert-Paare für die Online-Songs, löschen Sie die Online-Songs aus dem Kontext, speichern Sie den ursprünglichen Kontext und fügen Sie alle Online-Songs wieder in den ursprünglichen Kontext ein der gespeicherten Schlüssel-Wert-Paare.

4) Ich bin eine riesige n00b und vermisse etwas einfacher.

Danke!

+0

Was möchten Sie eigentlich speichern? Der Ort des Songs oder die tatsächlichen Song-Daten (Datei)? – sosborn

Antwort

8

Ich denke, die einfachste Sache zu tun wäre, eine zweite NSPersistentStore an Ihrem persistenten Speicherkoordinator angeschlossen zu haben. Sie können festlegen, dass dieser Speicher ein speicherinterner Speicher ist, und alle Ihre "Online" -Ergebnisse in diesem (temporären) Speicher speichern. Sie können angeben, in welchem ​​Speicher ein neu eingefügtes Objekt mit assignObject:toPersistentStore: gespeichert werden soll. Sobald Sie dies getan haben, können Sie frei speichern, da das "Speichern" nur im Speicher für Ihre Online-Songs passiert.

Wenn Sie dann einen Titel aus dem Online-Set in den permanenten Satz verschieben möchten, löschen Sie ihn einfach und fügen Sie ihn erneut ein, wobei Sie das neue Objekt mit derselben Methode Ihrem permanenten permanenten Speicher zuweisen.

Damit können Sie eine einzige NSManagedObjectContext an Ihre NSPersistentStoreCoordinator angeschlossen, die Objekte aus beiden der NSPersistentStore s sehen.

+0

Apple fördert die Verwendung mehrerer persistenter Speicher für ähnliche Szenarien (wie Starter-Daten, die mit der App mitgeliefert werden). Ich würde sagen, es ist eine gute Idee, wenn Sie Entitäten haben, deren persistente Speicherpläne sich unterscheiden. – rickster

+0

Große Antwort. Schätze, dass die Antwort auf meine Frage die Option # 4 war ... – rizzes

+1

Vorsicht, wenn Sie Beziehungen zwischen Entitäten pflegen, die verschiedene persistente Speicher verwenden. Laut unseren Freunden bei Apple: "Sie müssen darauf achten, keine Beziehungen von Instanzen in einem persistenten Speicher zu Instanzen in einem anderen persistenten Speicher zu erstellen, da dies nicht von Core Data unterstützt wird. Wenn Sie eine Beziehung zwischen Entitäten in verschiedenen Speichern erstellen müssen Normalerweise verwenden Sie geholte Eigenschaften "https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/CoreData/Articles/cdRelationships.html#//apple_ref/doc/uid/TP40001857-SW5 – NSTJ

5

Jesse's Lösung wird gut funktionieren.

Als weitere Option können Sie jedoch einfach einen verschachtelten Kontext verwenden, genau wie für einen detaillierten Prüfer.

Dieser Kontext kann alle Ihre "temporären" Elemente enthalten, aber da es ein Kind Ihres "Speichern" -Kontexts ist, funktionieren alle Abrufe einwandfrei.

NSManagedContext *tempContext = [[NSManagedContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType]; 
tempContext.parentContext = mainManagedObjectContext; 

All Ihre Sicherungen werden in mainManagedObjectContext eingefügt und mit save: gespeichert. Alle temporären Elemente werden in tempContext übernommen.

Hängen Sie Ihren abgerufenen Ergebniscontroller ebenfalls an den tempContext an.

Wenn Sie bereit sind, die temporären Elemente loszuwerden, setzen Sie den tempContext auf null.