Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Saving Single CoreData Entity (Not the Whole Context) While Keeping NSFetchedResultController Functionality

Phew, sorry for the long title.

I have a single Managed Object Context where I am storing songs derived from two different locations. I get some of the songs from the persistent storage on the phone (using Core Data), and I pull some of the songs from an online database. Both of the songs are of the same MananagedObject subclass. I would like both of these songs to be in a single context because I would like them both to show up on a table view connected with an NSFetchedResultsController.

The problem occurs when I would like to save one of the songs. I don't want to save all of the songs that I pulled from the online database to the phone. I just want to save the single song, so a simple [moc save] doesn't work. The other issue is that after I save the single song, I still want the songs pulled from online to be in the context (but again, not saved). I believe I have a couple of different options:

1) Is it possible to have an NSFetchedResults controller connected to multiple contexts?

2) I could move all of the songs pulled from the online database into a separate temporary context, save in the original context, and then move all of the songs back. (see: How do I copy or move an NSManagedObject from one context to another?)

3) Remember all of the key-value pairs for the online songs, delete the online songs from the context, save the original context, insert all of the online songs back into the original context based off of the saved key-value pairs.

4) I am a huge n00b and am missing something easier.

Thanks!

like image 495
rizzes Avatar asked Aug 08 '12 00:08

rizzes


2 Answers

I think the easiest thing to do would be to have a second NSPersistentStore attached to your persistent store coordinator. You can have that store be an in-memory store, and store all your "online" results in that (temporary) store. You can specify which store a newly-inserted object should be saved in with assignObject:toPersistentStore:. Once you've done this, you can save freely, since the "save" will only happen to memory for your online songs.

Then, when you want to move a song from the online set to the permanent set, just delete it and re-insert it, assigning the new object to your permanent persistent store with the same method.

This will let you use a single NSManagedObjectContext attached to your NSPersistentStoreCoordinator, which will see objects from both of the NSPersistentStores.

like image 165
Jesse Rusak Avatar answered Oct 05 '22 22:10

Jesse Rusak


Jesse's solution will work just fine.

However, as another option, you can simply use a nested context, just like you would for a detailed inspector.

That context can hold all your "temporary" items, but since it is a child of your "saving" context, all fetches will work just fine.

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

ALl your saves will be inserted into mainManagedObjectContext, and saved with save:. All your temporary items will go into tempContext.

Attach your fetched results controller to the tempContext as well.

When you are ready to get rid of the temporary items, just set the tempContext to nil.

like image 40
Jody Hagins Avatar answered Oct 05 '22 22:10

Jody Hagins