I have two Entities that have a relationship like so...
I want to create a fetched property on the conversation to return the most recent message that belongs to it. I don't want to have to maintain another relationship so having a fetched property seems like the way to go.
So what this boils down to is;
How can I limit the fetched property to one item?
and
How can I sort the items by timestamp?
You can use a fetched property to solve that problem but there is a catch.
You can't define that fetched property in the model editor.
You can define that fetched property in code.
So yes, you can do it but the value is very low.
Have you got an example of defining a fetched property in code? Where would I do this? The managedObjectModel?
Yes you would do this through the NSManagedObjectModel
.
You must do the edit before the model is added to a NSPersistentStoreCoordinator
. As soon as a NSManagedObjectModel
is added to a NSPersistentStoreCoordinator
it becomes immutable.
You grab the entity you care about and then then create a NSFetchedPropertyDescription
.
Add that NSFetchedPropertyDescription
to the existing entity.
Add the NSFetchRequest
to the created NSFetchedPropertyDescription
.
Once that is done you can then use the NSManagedObjectModel
like normal. Pretty straight forward other than having to reach into the model which is unusual. The order that you do things is important. Take this example:
NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"Model" withExtension:@"momd"];
NSManagedObjectModel *mom = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
ZAssert(mom, @"%@:%@ No model to generate a store from", [self class], NSStringFromSelector(_cmd));
//Inject a fetched property
NSEntityDescription *parentEntity = [mom entitiesByName][@"Parent"];
NSFetchedPropertyDescription *fetchedProperty = [[NSFetchedPropertyDescription alloc] init];
[fetchedProperty setName:@"lastTestEntity"];
NSMutableArray *properties = [[parentEntity properties] mutableCopy];
[properties addObject:fetchedProperty];
[parentEntity setProperties:properties];
NSFetchRequest *testEntityRequest = [[NSFetchRequest alloc] init];
[testEntityRequest setEntity:[mom entitiesByName][@"TestEntity"]];
[testEntityRequest setPredicate:[NSPredicate predicateWithFormat:@"parent == $FETCH_SOURCE"]];
[testEntityRequest setFetchLimit:1];
NSSortDescriptor *sortByDate = [NSSortDescriptor sortDescriptorWithKey:@"createDate" ascending:NO];
[testEntityRequest setSortDescriptors:@[sortByDate]];
[fetchedProperty setFetchRequest:testEntityRequest];
NSPersistentStoreCoordinator *coordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:mom];
ZAssert(coordinator, @"Failed to initialize coordinator");
Notice how I set the NSFetchRequest
after the NSFetchedProperty
has been added to the NSEntityDescription
. If you do not set it afterwards you will get an error from Core Data. Radar has been filed but I suspect very few people have even looked at this stuff let alone filed a radar against the odd behavior.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With