4
votes

I have an existing large app using plists to store its data. I store application state indicating current item selected, current user, and various other current selections in user defaults. This worked fine when the data was in plists. Now I'm refactoring to use Core Data instead of plists. I want to store a reference to an object instance as the currently viewed object. I know sqlite and Core Data have an ID for this object in the database, but I'm not sure what to store in user defaults. Three options come to mind:

  1. Generate my own sequential ID, store that with the objects I want to remember as "current", store that ID in user defaults.
  2. Try to use NSManagedObjectID and store in user defaults. I "think" I can convert it to a string as follows. Does this work?

    NSString *stringID = [[[managedObject objectID] URIRepresentation] absoluteString];

  3. I could create a current state entity in Core Data which is a singleton, only one row. This entity could have a to-one relationship to the current object I want to keep track of.

Suggestions appreciated for the approach with best design consideration.

Repeating from a comment, what are the drawbacks to approach #2? I've read conflicting accounts on the web. Some say the object ID is not consistent across migrations, yet Apple itself seems to suggest this as the solution.

In the Apple Class Reference for NSManagedObjectID, they discuss this very case and talk about saving the ID in user defaults. It says, "Object IDs can be transformed into a URI representation which can be archived and recreated later to refer back to a given object (using managedObjectIDForURIRepresentation: (NSPersistentStoreCoordinator) and objectWithID: (NSManagedObjectContext). For example, the last selected group in an application could be stored in the user defaults through the group object’s ID."

Does that mean the object ID URI representation always stays valid, even across migrations?

1

1 Answers

2
votes

You should use your own unique identifier (ideally which will not server only for the purpose of this question) for your objects and use this identifier to retrieve the object from Core Data and store this identifier in the NSUserDefaults. So, yours 1. solution is correct, though it need not to be sequential.

The 3. solution would work also, but it is not very clean.