Can I make instances of an NSManagedObject in no particular NSManagedObjectContext? - iphone

I'm building an app which receives a number of listings from a web API, and allows the user to save some for offline viewing. My usual approach would be:
Get the data from the API, and make a new Listing object for each datum
Save the object to the DB if the user chooses to do so.
But this is a Core Data app, so the context is what gets saved, not the object. Under those circumstances, the above would become something like this:
Get the data from the API, and make an unmanaged Listing object for each datum
Move the object into the managed context if the user chooses to do so, then save the context
One approach to having an unmanaged and a managed version of Listing objects would be to have two classes, e.g. ManagedListing and UnmanagedListing - but that's a horribly repetitive way of doing it.
What I'd like is to make Listing a subclass of NSManagedObject; initialise a bunch of them without an NSManagedObjectContext; then when I want to save one, I either set its context or I copy its attributes to a new Listing inside a context.
Can I make instances of an NSManagedObject in no particular NSManagedObjectContext? If so, how?

Use two persistent stores, one in memory and one on disk. If the user wants to save, move the object to the other store using assignObject:toPersistentStore:.

In iOS < 5.0 - yes.
In iOS >= 5.0 - no.

Related

Get changed objects in NSManagedObjectContext before saving?

I want to save changes on backend also, so I want to subclass NSManagedContext, override save method and loop al the changed object and call the appropriate RESTFull service. But how can I get the changed / inserted objects?
UPDATE:
I found that with setIncludesPendingChanges I can get the changed objects, but I still need to set the entity name for NSFetchRequest. But I want to fetch all different type of entites. How?
I found here a more appropriate solution based on NSManagedObjectContextDidSaveNotification: How to sync CoreData and a REST web service asynchronously and the same time properly propagate any REST errors into the UI

Open UIManagedDocument take too much time

Recently, I'm working with a timetable app in iOS, and i get trouble with Core Data.
My app has a main user interface kind of like the original calendar app created by Apple, and i save all my events data in the Core Data database.
I create a UIManagedDocument in order to fetch data from database by using its NSManagedObjectContext, and everything works just fine.
However, i need to use the NSManagedObjectContext to fetch data several times in several different view controllers during the runtime. And every time i do this, i need to reopen the UIManagedDocument, but open the document take too much time(it may take 2 seconds or even more, i have to display a spinner in view).
So here are my questions:
What's the right way to open a managedDocument?(I mean like open it during the lunch image time?)
Is there a way to only open the managedDocument once and keep it open during runtime?(So i can use its context all the time)
Does data store in the managedDocument i create?(I found that if i delete the document, data was gone)
Thanks.
You will get lots of different opinions on how to do this but basically you should only have to open the document once. This is done by some object that does the work and stores it so it can return it again when asked by a different view controller.
Many people create singleton's for this or put it in the App Delegate. I have implemented a protocol that lets me put it where ever it is convenient for a particular application without my other code having to know anything about the object that returns the information. As long as it responds to the protocol it can be the App Delegate, a singleton class, or any other object type.
See importing AppDelegate
The protocol that I put in the above example just returns information about where the database is. In my actual implementation I have an openDatabase method with a call back to let me know when it is done plus automatic initialization and updating methods.
You can also improve your performance by having the open operation happen off the main thread. This keeps your UI responsive but does not show the data any faster and you have to be carefull about managed object contexts and the threads they are in.
Good luck...

Where should I release an object? Can it release itself?

I want to get friends information from Facebook and save it with Core Data.
I build a FriendsManager Class that gets the a list of friends from Facebook (name and id)
and a FriendInfo Class that takes the id and gets all the info about this friend.
I thought I'd do it this way:
Create an object of FriendsManager let it get all my friends (not really a problem);
in the FriendsManager create an instance of FriendInfo;
give it the id and let it get all the info I need including geocoding of hometown;
save all this with core data.
But then where do I release this object?
In Order to get all the friends info I would create these objects in an loop that goes through my Array with friend ID's.
I also do all the getting info & geocoding with Grand Central Dispatch so do not really know when a FriendInfo got all the data it needs and is ready.
A Core Data object is usually a subclass of NSManagedObject, not a NSObject. You don't alloc or release it, you create one with the ManagedObjectContext and you either save or delete it but you don't release it because you don't own it.
A NSObject (prior to ARC) follows the usual rules of memory management - simply, if you get it through alloc, copy or a method starting with new, it is yours and you need to use release when you no longer use it. If you get it without allocating it - for example "NSString *string = [NSSTring stringWithFormat:#"test"]; then it is autoreleased and you don't need to release it.
Trust the analyser - shift-command-B.
Sounds like you might want to define your core data model and then create a NSManagedObject subclass for the friends information. You would create it using something like [NSEntityDescription insertNewObjectForEntityForName:#"FriendInfo" inManagedObjectContext:moc]; rather than [[FriendInfo alloc] init] as you would if it were a NSObject. The shift in thinking is that the object is created and managed by the ManagedObjectContext before you put any data in there, you request a new one and put in the data, then inform the ManagedObjectContext what you want done with that object - save or rollback (reverse all changes since the last save).
The problem you explain is rather "high-level" and it is difficult to give concrete advice. But in general you might want to just use ARC and don't hassle with most of these memory management problems you mentioned.
Also since you mentioned that you want to use core data, you would not release any of the objects you want to save since core data saves all objects of the context and so they never get "freed" anyway.
Your suggested approach about using a GeneralManagerClass to retrieve all the info and fill new instances of friends is generally OK. I also do it this way and it makes thinks relatively easy.
So I would just start with it and then ask more concrete questions. For now, I really don't see any general difficulty in the issues you mentioned if you follow the route you suggested...

Am I using Core Data properly by fetching an object once at startup and calling save when I want to persist the data?

I'm diving into iOS programming and am using Core Data in my app to persist the game data, however, I'm wondering if my approach is the wrong way to use Core Data. I have three tables in my DB, with the first two having a one-to-many relationship with the another table (i.e. UserProfile -->> Puzzle Packs -->> Puzzles).
The approach I'm taking to use and persist the data is simple, retrieve an instance of a UserProfile using a NSFetchedResultsController and store the UserProfile object as an instance var in my App Delegate. Then I use that UserProfile object throughout the rest of the code to access and modify the state of the puzzle packs and puzzles (representing the user's progress in the game) and whenever I make a change to the objects, I just call the NSManagedObjectContext's save method to update the DB, which is is also stored in the App Delegate.
My question is, should I be fetching data from the DB anytime I need to access or modify it or is my current approach, of fetching the top object once and calling the save method often, the correct way to use Core Data?
Thanks in advance for your wisdom! I apologize if my question is odd, I'm still a noob.
As long as you're only ever working with these objects with a single NSManagedObjectContext (ie, you never have to merge changes between contexts) then I don't see a problem with fetching once, and saving as needed.
That said, the moment you work with multiple contexts (for example, using NSOperation/NSOperationQueue or other multi-threading techniques, which require separate contexts), you'll want to make sure you merge changes and update other contexts so changes from one thread don't clobber something on another.

Approaches to save some NSManagedObjects but not others?

I'm working on a Core Data iPhone app that pulls remote resources from the web into NSManagedObjects and saves them locally.
I want the user to be able to designate which of these objects should be saved. This means that some will be saved, but many should be deleted. However, I might want to save and delete at different times - I'd prefer to save designated objects immediately (in case the app crashes), but still keep around the other objects because they're hanging out in table views and such.
One approach I can think of is to have a different persistent store - one for stuff that will be saved, one for stuff that won't; this way I can save the "should be saved" store at any time. However, I would much prefer to keep objects of the same type in the same domain.
Another approach would be to just save at the very end - negating any ability to recover from a crash. But saving at the end would allow me to parse out any objects that weren't designated "should save".
And that's really what I want - a "shouldSave" method in the NSManagedObject class, or at least a save method that I could fire at select objects. But as far as I can tell, neither of those exist.
So, if anyone has any other suggestions, please let me know! It would be greatly appreciated.
CoreData is not for object serialization, it is an object graph serialization. That is an important distinction. Once you have an NSManagedObject it is associated with a context, and CoreData handles saves at context level since that is the only way it guarantee any sort of object graph consistency. In other words, you can't save individual objects because if they have relationships with other objects you would need to also save those objects and it quickly cascades out to the whole graph.
You seem to be worried about crash recovery. If the app crashed and the user relaunched it would they expect to see just the items they saved, or everything that was on the screen before they crashed? If it is the former you should just delete them at save time and remove them from the users view (with some animation), if it is the later you should commit out everything, and potentially delete the objects you are not interested in at another time.