Save CoreData-entities in NSUserDefaults

papr picture papr · Feb 1, 2009 · Viewed 8.8k times · Source

Imagine an CoreData entity (e.g. named searchEngine).
NSManagedObjectContext manages some "instances" of this entity.
The end-user is going to be able to select his "standard searchEngine" with a NSPopupButton.
The selected object of NSPopupButton should be binded to the NSUserDefaults.
The problem:

1) @try{save}

a) If you try to save the selected "instance" directly to NSUserDefaults there comes something like this:

-[NSUserDefaults setObject:forKey:]: Attempt to insert non-property value ' (entity: searchEngine; id: 0x156f60  ; data: {
    url = "http://google.de/";
    someAttribute = 1;
    name = "google";
})' of class 'searchEngine'.

b) If you try to convert the "instance" to NSData comes this:

-[searchEngine encodeWithCoder:]: unrecognized selector sent to instance 0x1a25b0

So any idea how to get this entities in a plist-compatible data?

2) @try{registerDefaults}

Usually the registerDefaults: method is implemented in + (void)initialize. The problem here is that this method is called before CoreData loads the saved entities from his database. So I can't set a default to a no-existing object, right?

I know, long questions... but: try{[me provide:details]} ;D

Answer

mmalc picture mmalc · Jul 7, 2009

If you need to store a reference to a specific managed object, use the URI representation of its managed object ID:

NSURL *moIDURL = [[myManagedObject objectID] URIRepresentation];

You can then save the URL to user defaults.

To retrieve the managed object, you use:

NSManagedObjectID *moID = [myPersistentStoreCoordinator managedObjectIDForURIRepresentation:moIDURL];
NSManagedObject *myManagedObject = [myContext objectWithID:moID];

The only caveat is that you must ensure that the original managed object ID is permanent -- this is not a problem if you've already saved the object, alternatively you can use obtainPermanentIDsForObjects:error:.