Search code examples
core-dataios5nspredicatensfetchrequest

How can I know the class type of an abstract entity in a NSPredicate?


Using core data I'd like to fetch some data. My model uses some abstract entities, see attached picture, where QuantifiedIngredient is an abstract class. I'd like to fetch Ingredient entities that have at least one RecipeQuantifiedIngredients, but in the middle is QuantifiedIngredient, which is an abstract class.

How can I do that, how can I test the actual type of an abstract class inside a NSPredicate? Any idea or suggestion?

enter image description here

The only clue I found was: How can you reference child entity name in a predicate for a fetch request of the parent entity?

Would work a custom property in my QuantifiedIngredient to know if it is a RecipeQuantifiedIngredient? For instance isRecipeQuantifiedIngredient?

Thanks a lot for your help.


Solution

  • I don't want to take the time to translate this into CoreData-speak so here is my thought in SQL:

    SELECT * FROM quantifiedIngredients WHERE recipe <> NULL
    

    or something like that. This is essentially Nikita's suggestion of using a flag, except that the 'flag' is the existence of a property. I don't know how CoreData will react when faced with GroceryQuantifiedIngredients that don't have the recipe, I think KVO will throw an exception. You might be so bold as to add a category:

    @interface GroceryQuantifiedIngredients (KVOHack)
    -(id)recipe;
    @end
    
    @implementation GroceryQuantifiedIngredients (KVOHack)
    -(id) recipe { return nil; }
    @end
    

    This would of course require CoreData to enumerate all quantifiedIngredients, but I presume it will have to do so anyway, and a the return nil should optimize into tiny code. The other consideration is whether this will have a bad effect on the rest of your code; you will have to make that call.

    Another idea which pops to mind as I finish this up is to do something like this (I'm getting really loose with my pseudo-code now):

    SELECT * FROM quantifiedIngredients WHERE [i respondsToSelector:@selector(recipe)];
    

    See what I mean? I forget whether CoreData lets you play with some kind of cursor when working with predicates or fetchedThingamabobbers, if it does than I think this is your best bet. Anyway it's Sunday afternoon so that stuff is left as a exercise for the reader.

    +1 for a good question.