Search code examples
objective-cioscore-dataone-to-manynsfetchrequest

How to access CoreData entities based on a to-many relationship of another entity?


I am learning CoreData with a sample inventory app. My Data Model has 2 entities, "Possession" and "Asset Type". Possessions have a to-one relationship to Asset Types called "assetType" and Asset Types have a to-many relationship to Possessions named "possessions". Each Possession has only one Asset Type, but Asset Types have many Possessions.

I'd like to sort a tableview into sections based on asset types. I need some help populating my data structure for this though.

Here is how I'll model my table view controller

NSArray for table sections each section object in the array will be an NSDictionary with 2 keys, @"Header" - which will be the Asset Type, and @"Possessions" which is an array of possessions of that asset type.

I can handle building my table view from this structure no problem. I can also handle fetching the Asset Types from CoreData into the header key of my dictionary. Where I am stumped is how do I take advantage of the to-many relationship that asset types have to possessions so I can get the possessions into an array for the dictionary.

How do I get each Asset Type's possessions into an array?

Do I need to make a fetch request with a predicate to fetch possessions that have the matching asset type, or is there a simpler way? - Seems that would be inefficient as it would have to check all possessions for a match!?!?!?!?

Is the to-many relationship "possessions" of AssetType entity an accessible property of the AssetType entity? If so how do I access it? What does it return?

I am not looking for free code, but I am willing to post mine if needed. What I'd really like is to know the best way to solve this problem and maybe pointed to helpful info online to accomplish this. I am not a complete newb, but I am still having trouble wrapping my head around CoreData and thus far the Apple docs are still pretty confusing to me on this subject. I am appreciative for any help offered.


Solution

  • If you've created your AssetType class with Xcode default NSManagedObject template (see image)

    File/New/File.../Core Dats/NSManagedObject subclass

    you should have something like that in your AssetType.h:

    @interface AssetType : NSManagedObject
    
    @property (nonatomic, retain) NSSet *possessions;
    
    @end
    
    @interface AssetType (CoreDataGeneratedAccessors)
    
    - (void) addPossessionsObject:    (Possession *) value;
    - (void) removePossessionsObject: (Possession *) value;
    - (void) addPossessions:          (NSSet *) value;
    - (void) removePossessions:       (NSSet *) value
    
    @end
    

    So if you have an AssetType object, you can access all Possession objects related to it via the possessions property. It is not ordered by default though, so to access these objects as an array, you will need to call the -allObjects method of the set which returns the objects within the set as an array and then probably sort these objects somehow.

    Edit:

    Also, even if you did not create the NSManagedObject subclass that way and it does not have the possessions property implemented yet, you could add this property to the class in the just same way as stated in the example above and implement it within the AssetType.m as @dynamic possessions.