views:

280

answers:

2

Building on this question, I've managed to use undo groups and a single managed object context to handle adding a Cocktail that can reference existing Ingredients and/or Brands.

Now I'm stuck with a UI nit -- in the fetched results controller (sorted by cocktail.name) you can briefly see an empty row for the to-be-added Cocktail. Marcus Zarra suggested:

You can add to the predicate to filter out unsaved objects, for example by using (entity.isTemporaryID == NO).

but every iteration I've tried comes back with errors of the form

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'keypath entity.isTemporaryID not found in entity <NSSQLEntity Cocktail id=4>'

How can one execute the equivalent of [[cocktail objectID] isTemporaryID] in an NSPredicate?

A: 

The call is on the objectID not the managed object:

BOOL isTemporary = [[managedObject objectID] isTemporaryID];

See this section of the Core Data Programming guide for more details.

I'm not sure why you're seeing an empty row for an unadded entity. If the entity hasn't been added then it should be fetched by the fetched results controller. It sounds like you have inserted the entity into the context but have not yet populated it.

If that is the case, you can use a predicate to exclude entities that have some or all of their properties empty. If you end up doing this a lot, you might want to add a flag property to the class which will return NO (via a custom getter) if entity is not in a state to be displayed.

TechZen
Your case is correct -- the entity has been added but not yet populated in the detail controller. I was hoping to use a predicate on the temporary objectID rather than check for empty keys or add a flag to the data model.
iPhoneDollaraire
You also have the option of creating the object first and then adding it to the managed object context later. If you do it that way, then the object doesn't show in fetches until you do add it.
TechZen
A: 
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'keypath entity.isTemporaryID not found in entity <NSSQLEntity Cocktail id=4>'

How can one execute the equivalent of [[cocktail objectID] isTemporaryID] in an NSPredicate?

Do that.

What you asked for is not [[cocktail objectID] isTemporaryID], it's [[cocktail entity] isTemporaryID]. If you want objectID (which you do, since you want to ask it whether it's a temporary ID), then that's what you need to ask for in your key path.

You should read the Key-Value Coding Programming Guide, even if you've read it already, and look up the entity and objectID methods in the NSManagedObject reference. From these, you'll find it clear that Marcus Zarra either mixed the two up or meant objectID but typed entity by accident. It happens to everyone—that's why it's good to always check the docs.

Peter Hosey
Agreed -- but what I'm looking for is the effect of that Objective-C method in the predicate itself, so that the fetched results controller doesn't list the unsaved entity.
iPhoneDollaraire
I understand that (well, everything up to “so that”—I'm not an iPhone developer, so I know nothing of fetched results controllers). You will have the predicate call that method, by naming that method in the key path. Again, see the KVC Programming Guide.
Peter Hosey