RunLoop
RunLoop

Reputation: 20376

Core Data - Get objectIDs of to-many relationship without firing a fault

I have an entity with a to-many relationship. After I fetch a subset of objects from my entity, I would like to get the ManagedObjectIDs of the relationship objects - without firing a fault. Is this possible? My understanding from the documentation is that calling objectID on a fault does not cause it to fire, but when I try the following line, a fault is fired for each object's relationship nonetheless:

[word.articles valueForKeyPath:@"objectID"];

I have also tried the following, with the same result:

[word valueForKeyPath:@"articles.objectID"];

I have now also tried the following, but unfortunately article faults still fire:

for (Article *article in word.articles) {

   [articleIDs addObject:article.objectID];
}

Any help would be greatly appreciated please!

Upvotes: 3

Views: 1755

Answers (4)

malhal
malhal

Reputation: 30719

This was made possible in iOS 8.3

/* returns an array of objectIDs for the contents of a relationship. 
   to-one relationships will return an NSArray with a single 
   NSManagedObjectID.  Optional relationships may return an empty 
   NSArray. 
   The objectIDs will be returned in an NSArray regardless of the type 
   of the relationship.  */
- (NSArray<NSManagedObjectID *> *)objectIDsForRelationshipNamed:(NSString *)key NS_AVAILABLE(10_11,8_3);

It does one trip to the store to get all the IDs.

Upvotes: 4

TPoschel
TPoschel

Reputation: 3872

One possibility would be to perform prefetching so that your relationship objects are fetched during your initial fetch and therefore will not cause faults later.

Look into the relationshipKeyPathsForPrefetching property in the NSFetchRequest class. Here is an example where the request is returning an array of Word objects that contain an articles property:

[request setRelationshipKeyPathsForPrefetching:@[@"articles"]];

Upvotes: 0

Robin Summerhill
Robin Summerhill

Reputation: 13675

What you need to do is create an NSFetchRequest for the Articles entity using a predicate like this (where 'word' is a word managed object):

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(ANY words == %@)", word];

Set resultType = NSManagedObjectIDResultType as Ashley says in his answer.

The fetch request will then return a collection of Article ObjectIDs for articles containing the specified word.

OR: If you want to look up by the text of the word rather than fetching it as a managed object first then use a predicate like this. (where 'wordText' is an NSString and assuming - 'text' is a field of the Word entity)

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(ANY words.text == %@)", wordText];

Upvotes: 1

Ashley Mills
Ashley Mills

Reputation: 53171

I think you might have to use an NSFetchRequest, for entity Articles, and setting

request.resultType = NSManagedObjectIDResultType

If the problem is multiple faults firing (so multiple SQL requests), how about a fetch request to fetch all your required Articles initially, meaning only a single SQL request is made?

Upvotes: 0

Related Questions